.do
API Reference

Events API

Publish and consume business events for event-driven architectures

Publish and consume business events for event-driven architectures. Events represent important occurrences in your business that other systems may need to react to.

Overview

Business events are notifications of occurrences that:

  • Represent important business moments
  • Enable event-driven architectures
  • Trigger workflows and actions
  • Include timestamps and context
  • Can be filtered and subscribed to
import { createBusinessApi } from 'business-as-code'

const api = createBusinessApi({
  apiKey: process.env.APIS_DO_KEY,
})

// Publish an event
await api.events.publish({
  type: 'order.created',
  timestamp: new Date().toISOString(),
  source: 'order-service',
  data: {
    orderId: 'order-123',
    customerId: 'cust-456',
    total: 199.99,
  },
})

publish()

Publish a business event.

Signature

publish(
  event: Omit<BusinessEvent, 'id'>
): Promise<BusinessEvent>

Parameters

ParameterTypeRequiredDescription
eventobjectYesEvent data without ID

Event Properties

PropertyTypeRequiredDescription
typestringYesEvent type (e.g., 'order.created')
timestampstringYesWhen event occurred (ISO 8601)
sourcestringYesEvent source/origin
dataobjectYesEvent payload data
resourcesBusinessResource[]NoRelated resources
metadataobjectNoAdditional metadata

Returns

Promise that resolves to the published BusinessEvent with generated ID.

Example

const event = await api.events.publish({
  type: 'customer.registered',
  timestamp: new Date().toISOString(),
  source: 'auth-service',
  data: {
    customerId: 'cust-789',
    email: '[email protected]',
    plan: 'pro',
    referralSource: 'google-ads',
  },
  resources: [{ $type: 'Customer', $id: 'cust-789' }],
  metadata: {
    version: '1.0',
    region: 'us-west-2',
  },
})

console.log('Event published:', event.id)

Event Types

Commerce Events

Track the complete order lifecycle from creation to delivery:

// Order lifecycle
await api.events.publish({
  type: 'order.created', // → https://events.org.ai/Order.created
  timestamp: new Date().toISOString(),
  source: 'order-service',
  data: { orderId: 'order-123', total: 199.99 },
})

await api.events.publish({
  type: 'order.paid', // → https://events.org.ai/Order.paid
  timestamp: new Date().toISOString(),
  source: 'payment-service',
  data: { orderId: 'order-123', paymentId: 'pay-456' },
})

await api.events.publish({
  type: 'order.shipped', // → https://events.org.ai/Order.shipped
  timestamp: new Date().toISOString(),
  source: 'fulfillment-service',
  data: { orderId: 'order-123', trackingNumber: 'TRACK-789' },
})

await api.events.publish({
  type: 'order.delivered', // → https://events.org.ai/Order.delivered
  timestamp: new Date().toISOString(),
  source: 'shipping-service',
  data: { orderId: 'order-123', deliveryDate: '2024-10-30' },
})

await api.events.publish({
  type: 'order.cancelled', // → https://events.org.ai/Order.cancelled
  timestamp: new Date().toISOString(),
  source: 'order-service',
  data: { orderId: 'order-123', reason: 'customer-request' },
})

Semantic Abstractions: Order.created · Order.paid · Order.shipped · Order.delivered · Order.cancelled

Customer Events

Track customer journey from registration through lifecycle milestones:

// Customer lifecycle
await api.events.publish({
  type: 'customer.registered', // → https://events.org.ai/Customer.registered
  timestamp: new Date().toISOString(),
  source: 'auth-service',
  data: { customerId: 'cust-123', email: '[email protected]' },
})

await api.events.publish({
  type: 'customer.verified', // → https://events.org.ai/Customer.verified
  timestamp: new Date().toISOString(),
  source: 'auth-service',
  data: { customerId: 'cust-123', method: 'email' },
})

await api.events.publish({
  type: 'customer.upgraded', // → https://events.org.ai/Customer.upgraded
  timestamp: new Date().toISOString(),
  source: 'billing-service',
  data: { customerId: 'cust-123', from: 'basic', to: 'pro' },
})

await api.events.publish({
  type: 'customer.churned', // → https://events.org.ai/Customer.churned
  timestamp: new Date().toISOString(),
  source: 'subscription-service',
  data: { customerId: 'cust-123', reason: 'pricing' },
})

Semantic Abstractions: Customer.registered · Customer.verified · Customer.upgraded · Customer.churned

Payment Events

Track payment processing from initiation to completion:

// Payment lifecycle
await api.events.publish({
  type: 'payment.initiated', // → https://events.org.ai/Payment.initiated
  timestamp: new Date().toISOString(),
  source: 'payment-service',
  data: { paymentId: 'pay-123', amount: 99.99 },
})

await api.events.publish({
  type: 'payment.succeeded', // → https://events.org.ai/Payment.succeeded
  timestamp: new Date().toISOString(),
  source: 'payment-service',
  data: { paymentId: 'pay-123', transactionId: 'txn-456' },
})

await api.events.publish({
  type: 'payment.failed', // → https://events.org.ai/Payment.failed
  timestamp: new Date().toISOString(),
  source: 'payment-service',
  data: { paymentId: 'pay-123', error: 'insufficient-funds' },
})

await api.events.publish({
  type: 'payment.refunded', // → https://events.org.ai/Payment.refunded
  timestamp: new Date().toISOString(),
  source: 'payment-service',
  data: { paymentId: 'pay-123', refundAmount: 99.99 },
})

Semantic Abstractions: Payment.initiated · Payment.succeeded · Payment.failed · Payment.refunded

Content Events

Track content creation, publication, and engagement:

// Content lifecycle
await api.events.publish({
  type: 'article.created', // → https://events.org.ai/Article.created
  timestamp: new Date().toISOString(),
  source: 'cms',
  data: { articleId: 'article-123', authorId: 'author-456' },
})

await api.events.publish({
  type: 'article.published', // → https://events.org.ai/Article.published
  timestamp: new Date().toISOString(),
  source: 'cms',
  data: { articleId: 'article-123', url: 'https://blog.example.com/...' },
})

await api.events.publish({
  type: 'article.viewed', // → https://events.org.ai/Article.viewed
  timestamp: new Date().toISOString(),
  source: 'analytics',
  data: { articleId: 'article-123', userId: 'user-789', duration: 180 },
})

Semantic Abstractions: Article.created · Article.published · Article.viewed

list()

List events with optional filters.

Signature

list(
  filters?: Record<string, any>
): Promise<BusinessEvent[]>

Parameters

ParameterTypeRequiredDescription
filtersobjectNoFilter criteria

Returns

Promise that resolves to an array of BusinessEvent objects.

Example

// Get all events
const events = await api.events.list()

// Get events with filters
const orderEvents = await api.events.list({
  type: 'order.created',
  source: 'order-service',
})

// Client-side filtering
const recentEvents = events.filter((e) => {
  const eventDate = new Date(e.timestamp)
  const oneDayAgo = new Date(Date.now() - 86400000)
  return eventDate > oneDayAgo
})

// Filter by resource
const customerEvents = events.filter((e) => e.resources?.some((r) => r.$type === 'Customer' && r.$id === 'cust-123'))

get()

Retrieve a specific event by ID.

Signature

get(id: string): Promise<BusinessEvent>

Parameters

ParameterTypeRequiredDescription
idstringYesUnique identifier of the event

Returns

Promise that resolves to a BusinessEvent object.

Example

const event = await api.events.get('event-abc123')

console.log('Event type:', event.type)
console.log('Timestamp:', event.timestamp)
console.log('Source:', event.source)
console.log('Data:', event.data)

Event-Driven Workflows

Trigger workflows when events occur:

// Create workflow triggered by event
await api.workflows.create({
  name: 'Process New Order',
  steps: [
    {
      id: 'validate',
      name: 'Validate Order',
      type: 'function',
      function: 'validate-order',
      next: 'charge-payment',
    },
    {
      id: 'charge-payment',
      name: 'Charge Payment',
      type: 'function',
      function: 'process-payment',
      next: 'send-confirmation',
    },
    {
      id: 'send-confirmation',
      name: 'Send Confirmation',
      type: 'function',
      function: 'send-email',
    },
  ],
  triggers: [
    {
      type: 'event',
      config: {
        eventType: 'order.created',
      },
    },
  ],
})

// Publish event (triggers workflow automatically)
await api.events.publish({
  type: 'order.created',
  timestamp: new Date().toISOString(),
  source: 'order-service',
  data: { orderId: 'order-123' },
})

Complete Examples

E-commerce Order Processing

// 1. Order created
await api.events.publish({
  type: 'order.created',
  timestamp: new Date().toISOString(),
  source: 'order-service',
  data: {
    orderId: 'order-123',
    customerId: 'cust-456',
    items: [{ productId: 'prod-1', quantity: 2, price: 49.99 }],
    total: 99.98,
  },
  resources: [
    { $type: 'Order', $id: 'order-123' },
    { $type: 'Customer', $id: 'cust-456' },
  ],
})

// 2. Payment processed
await api.events.publish({
  type: 'payment.succeeded',
  timestamp: new Date().toISOString(),
  source: 'payment-service',
  data: {
    paymentId: 'pay-789',
    orderId: 'order-123',
    amount: 99.98,
    method: 'credit-card',
  },
  resources: [
    { $type: 'Payment', $id: 'pay-789' },
    { $type: 'Order', $id: 'order-123' },
  ],
})

// 3. Inventory updated
await api.events.publish({
  type: 'inventory.decremented',
  timestamp: new Date().toISOString(),
  source: 'inventory-service',
  data: {
    productId: 'prod-1',
    quantity: 2,
    newStock: 48,
    reason: 'order-fulfillment',
    orderId: 'order-123',
  },
})

// 4. Shipment created
await api.events.publish({
  type: 'shipment.created',
  timestamp: new Date().toISOString(),
  source: 'fulfillment-service',
  data: {
    shipmentId: 'ship-456',
    orderId: 'order-123',
    carrier: 'FedEx',
    trackingNumber: 'TRACK-123456',
    estimatedDelivery: '2024-10-30',
  },
  resources: [
    { $type: 'Shipment', $id: 'ship-456' },
    { $type: 'Order', $id: 'order-123' },
  ],
})

Customer Lifecycle

// Registration
await api.events.publish({
  type: 'customer.registered',
  timestamp: new Date().toISOString(),
  source: 'auth-service',
  data: {
    customerId: 'cust-new-123',
    email: '[email protected]',
    source: 'organic',
    referrer: 'https://google.com',
  },
})

// Email verification
await api.events.publish({
  type: 'customer.verified',
  timestamp: new Date().toISOString(),
  source: 'auth-service',
  data: {
    customerId: 'cust-new-123',
    verificationMethod: 'email',
    verifiedAt: new Date().toISOString(),
  },
})

// First purchase
await api.events.publish({
  type: 'customer.first_purchase',
  timestamp: new Date().toISOString(),
  source: 'order-service',
  data: {
    customerId: 'cust-new-123',
    orderId: 'order-first-456',
    amount: 99.99,
    daysToConvert: 3,
  },
})

// Subscription upgrade
await api.events.publish({
  type: 'subscription.upgraded',
  timestamp: new Date().toISOString(),
  source: 'billing-service',
  data: {
    customerId: 'cust-new-123',
    subscriptionId: 'sub-789',
    previousPlan: 'basic',
    newPlan: 'pro',
    effectiveDate: '2024-11-01',
  },
})

System Monitoring

// Error occurred
await api.events.publish({
  type: 'system.error',
  timestamp: new Date().toISOString(),
  source: 'api-server',
  data: {
    error: 'DatabaseConnectionError',
    message: 'Failed to connect to database',
    severity: 'high',
    service: 'order-service',
    endpoint: '/api/orders',
  },
  metadata: {
    stackTrace: '...',
    requestId: 'req-123',
  },
})

// Service degraded
await api.events.publish({
  type: 'system.degraded',
  timestamp: new Date().toISOString(),
  source: 'monitoring',
  data: {
    service: 'payment-service',
    metric: 'response_time',
    threshold: 1000,
    actual: 2500,
    duration: 300,
  },
})

// Service recovered
await api.events.publish({
  type: 'system.recovered',
  timestamp: new Date().toISOString(),
  source: 'monitoring',
  data: {
    service: 'payment-service',
    downtime: 180,
    recoveredAt: new Date().toISOString(),
  },
})

Event Patterns

Event Sourcing

// Record all state changes as events
await api.events.publish({
  type: 'order.status_changed',
  timestamp: new Date().toISOString(),
  source: 'order-service',
  data: {
    orderId: 'order-123',
    previousStatus: 'pending',
    newStatus: 'processing',
    changedBy: 'system',
  },
})

await api.events.publish({
  type: 'order.status_changed',
  timestamp: new Date().toISOString(),
  source: 'order-service',
  data: {
    orderId: 'order-123',
    previousStatus: 'processing',
    newStatus: 'shipped',
    changedBy: 'fulfillment-service',
  },
})

// Rebuild state from events
const orderEvents = await api.events.list({
  type: 'order.status_changed',
  'data.orderId': 'order-123',
})

const currentState = orderEvents.reduce(
  (state, event) => ({
    ...state,
    status: event.data.newStatus,
    lastUpdated: event.timestamp,
  }),
  {}
)

CQRS (Command Query Responsibility Segregation)

// Command: Write event
await api.events.publish({
  type: 'product.price_updated',
  timestamp: new Date().toISOString(),
  source: 'pricing-service',
  data: {
    productId: 'prod-123',
    previousPrice: 99.99,
    newPrice: 89.99,
    reason: 'promotion',
  },
})

// Query: Read materialized view (updated by event consumer)
const product = await api.resources.get('Product', 'prod-123')
console.log('Current price:', product.price) // 89.99

Saga Pattern

// Multi-step distributed transaction using events

// Step 1: Reserve inventory
await api.events.publish({
  type: 'saga.inventory_reserved',
  timestamp: new Date().toISOString(),
  source: 'inventory-service',
  data: {
    sagaId: 'saga-order-123',
    productId: 'prod-456',
    quantity: 2,
  },
})

// Step 2: Charge payment
await api.events.publish({
  type: 'saga.payment_charged',
  timestamp: new Date().toISOString(),
  source: 'payment-service',
  data: {
    sagaId: 'saga-order-123',
    paymentId: 'pay-789',
    amount: 99.98,
  },
})

// Compensating transaction if step fails
await api.events.publish({
  type: 'saga.inventory_released',
  timestamp: new Date().toISOString(),
  source: 'inventory-service',
  data: {
    sagaId: 'saga-order-123',
    productId: 'prod-456',
    quantity: 2,
    reason: 'payment-failed',
  },
})

Best Practices

1. Use Descriptive Event Types

// ✅ Good - clear, hierarchical
await api.events.publish({
  type: 'order.payment.succeeded',
  ...
})

// ❌ Avoid - vague
await api.events.publish({
  type: 'update',
  ...
})

2. Include Rich Context

// ✅ Good - comprehensive data
await api.events.publish({
  type: 'order.created',
  timestamp: new Date().toISOString(),
  source: 'order-service',
  data: {
    orderId: 'order-123',
    customerId: 'cust-456',
    total: 199.99,
    currency: 'USD',
    items: [...],
    shippingAddress: {...}
  },
  resources: [
    { $type: 'Order', $id: 'order-123' },
    { $type: 'Customer', $id: 'cust-456' }
  ],
  metadata: {
    version: '1.0',
    region: 'us-west',
    correlationId: 'corr-abc'
  }
})

3. Use Timestamps

// ✅ Good - ISO 8601 timestamp
await api.events.publish({
  type: 'event.occurred',
  timestamp: new Date().toISOString(), // 2024-10-27T10:30:00.000Z
  ...
})

4. Version Events

// Include version in metadata for schema evolution
await api.events.publish({
  type: 'order.created',
  timestamp: new Date().toISOString(),
  source: 'order-service-v2',
  data: {...},
  metadata: {
    version: '2.0',
    schemaVersion: 'order-created-v2'
  }
})

Next Steps