.do
API Reference

Metrics API

Track KPIs, OKRs, and business metrics for analytics and monitoring

Track KPIs, OKRs, and business metrics for analytics and monitoring. Measure business performance and make data-driven decisions.

Overview

Business metrics provide quantitative measurements for:

  • Key Performance Indicators (KPIs)
  • Objectives and Key Results (OKRs)
  • Counters (incremental values)
  • Gauges (current values)
  • Histograms (distributions)
import { createBusinessApi } from 'business-as-code'

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

// Record a metric
await api.metrics.record({
  name: 'Monthly Recurring Revenue',
  type: 'kpi',
  value: 125000,
  unit: 'USD',
  timestamp: new Date().toISOString(),
})

record()

Record a business metric.

Signature

record(
  metric: Omit<BusinessMetric, 'id'>
): Promise<BusinessMetric>

Parameters

ParameterTypeRequiredDescription
metricobjectYesMetric data without ID

Metric Properties

PropertyTypeRequiredDescription
namestringYesMetric name
typestringYesMetric type ('kpi', 'okr', 'counter', 'gauge', 'histogram')
valuenumber | stringYesMetric value
targetnumber | stringNoTarget value (for KPIs/OKRs)
unitstringNoUnit of measurement
timestampstringNoWhen measured (ISO 8601)
metadataobjectNoAdditional context

Returns

Promise that resolves to the recorded BusinessMetric with generated ID.

Example

// Record revenue metric
const metric = await api.metrics.record({
  name: 'Monthly Recurring Revenue',
  type: 'kpi',
  value: 125000,
  target: 150000,
  unit: 'USD',
  timestamp: new Date().toISOString(),
  metadata: {
    period: '2024-10',
    growth: 0.15,
    newCustomers: 12,
  },
})

console.log('Metric recorded:', metric.id)

Metric Types

KPI (Key Performance Indicator)

// Revenue metrics
await api.metrics.record({
  name: 'Monthly Recurring Revenue',
  type: 'kpi',
  value: 125000,
  target: 150000,
  unit: 'USD',
})

await api.metrics.record({
  name: 'Annual Recurring Revenue',
  type: 'kpi',
  value: 1500000,
  target: 2000000,
  unit: 'USD',
})

// Customer metrics
await api.metrics.record({
  name: 'Customer Acquisition Cost',
  type: 'kpi',
  value: 250,
  target: 200,
  unit: 'USD',
})

await api.metrics.record({
  name: 'Customer Lifetime Value',
  type: 'kpi',
  value: 5000,
  target: 6000,
  unit: 'USD',
})

await api.metrics.record({
  name: 'Churn Rate',
  type: 'kpi',
  value: 0.05,
  target: 0.03,
  unit: 'percentage',
})

// Product metrics
await api.metrics.record({
  name: 'Daily Active Users',
  type: 'kpi',
  value: 15000,
  target: 20000,
  unit: 'users',
})

await api.metrics.record({
  name: 'Net Promoter Score',
  type: 'kpi',
  value: 45,
  target: 50,
  unit: 'score',
})

OKR (Objectives and Key Results)

// Objective: Increase revenue
await api.metrics.record({
  name: 'Q4 Revenue Growth',
  type: 'okr',
  value: 0.18, // 18% growth
  target: 0.25, // 25% target
  unit: 'percentage',
  metadata: {
    objective: 'Accelerate Revenue Growth',
    keyResult: 'Achieve 25% QoQ growth',
    quarter: 'Q4-2024',
  },
})

// Objective: Improve product
await api.metrics.record({
  name: 'Feature Adoption Rate',
  type: 'okr',
  value: 0.42, // 42% adoption
  target: 0.6, // 60% target
  unit: 'percentage',
  metadata: {
    objective: 'Increase Product Engagement',
    keyResult: 'Reach 60% feature adoption',
    feature: 'automation-builder',
  },
})

// Objective: Expand market
await api.metrics.record({
  name: 'Enterprise Customers',
  type: 'okr',
  value: 45,
  target: 100,
  unit: 'customers',
  metadata: {
    objective: 'Expand Enterprise Market',
    keyResult: 'Acquire 100 enterprise customers',
  },
})

Counter

// Incrementing counters
await api.metrics.record({
  name: 'Total Orders',
  type: 'counter',
  value: 1523,
  unit: 'orders',
})

await api.metrics.record({
  name: 'API Requests',
  type: 'counter',
  value: 1000000,
  unit: 'requests',
})

await api.metrics.record({
  name: 'Emails Sent',
  type: 'counter',
  value: 50000,
  unit: 'emails',
})

Gauge

// Current state values
await api.metrics.record({
  name: 'Active Subscriptions',
  type: 'gauge',
  value: 1250,
  unit: 'subscriptions',
})

await api.metrics.record({
  name: 'Server CPU Usage',
  type: 'gauge',
  value: 0.65,
  unit: 'percentage',
  metadata: {
    server: 'api-server-1',
    region: 'us-west',
  },
})

await api.metrics.record({
  name: 'Queue Length',
  type: 'gauge',
  value: 42,
  unit: 'items',
})

Histogram

// Distribution of values
await api.metrics.record({
  name: 'Order Value Distribution',
  type: 'histogram',
  value: JSON.stringify({
    buckets: [
      { range: '0-50', count: 120 },
      { range: '50-100', count: 85 },
      { range: '100-500', count: 45 },
      { range: '500+', count: 12 },
    ],
  }),
  metadata: {
    period: '2024-10',
    totalOrders: 262,
  },
})

await api.metrics.record({
  name: 'Response Time Distribution',
  type: 'histogram',
  value: JSON.stringify({
    p50: 150,
    p90: 300,
    p95: 450,
    p99: 1000,
  }),
  unit: 'milliseconds',
})

list()

List all metrics, optionally filtered.

Signature

list(): Promise<BusinessMetric[]>

Returns

Promise that resolves to an array of BusinessMetric objects.

Example

const metrics = await api.metrics.list()

console.log(`Found ${metrics.length} metrics`)

// Filter by type
const kpis = metrics.filter((m) => m.type === 'kpi')
const okrs = metrics.filter((m) => m.type === 'okr')

// Filter by date
const thisMonth = metrics.filter((m) => {
  const metricDate = new Date(m.timestamp)
  const now = new Date()
  return metricDate.getMonth() === now.getMonth() && metricDate.getFullYear() === now.getFullYear()
})

// Calculate progress
kpis.forEach((kpi) => {
  const progress = kpi.target ? (Number(kpi.value) / Number(kpi.target)) * 100 : null

  console.log(`${kpi.name}: ${kpi.value} / ${kpi.target} (${progress?.toFixed(1)}%)`)
})

get()

Retrieve a specific metric by ID.

Signature

get(id: string): Promise<BusinessMetric>

Parameters

ParameterTypeRequiredDescription
idstringYesUnique identifier of the metric

Returns

Promise that resolves to a BusinessMetric object.

Example

const metric = await api.metrics.get('metric-abc123')

console.log('Metric:', metric.name)
console.log('Type:', metric.type)
console.log('Value:', metric.value)
console.log('Target:', metric.target)
console.log('Progress:', (Number(metric.value) / Number(metric.target)) * 100 + '%')

Complete Examples

SaaS Dashboard Metrics

// Revenue metrics
await api.metrics.record({
  name: 'Monthly Recurring Revenue',
  type: 'kpi',
  value: 125000,
  target: 150000,
  unit: 'USD',
  timestamp: new Date().toISOString(),
})

await api.metrics.record({
  name: 'Annual Run Rate',
  type: 'kpi',
  value: 1500000,
  unit: 'USD',
})

// Customer metrics
await api.metrics.record({
  name: 'Total Customers',
  type: 'gauge',
  value: 1250,
  unit: 'customers',
})

await api.metrics.record({
  name: 'New Customers (MTD)',
  type: 'counter',
  value: 42,
  unit: 'customers',
})

await api.metrics.record({
  name: 'Churned Customers (MTD)',
  type: 'counter',
  value: 5,
  unit: 'customers',
})

// Engagement metrics
await api.metrics.record({
  name: 'Daily Active Users',
  type: 'gauge',
  value: 8500,
  unit: 'users',
})

await api.metrics.record({
  name: 'Weekly Active Users',
  type: 'gauge',
  value: 15000,
  unit: 'users',
})

// Financial metrics
await api.metrics.record({
  name: 'Customer Acquisition Cost',
  type: 'kpi',
  value: 250,
  target: 200,
  unit: 'USD',
})

await api.metrics.record({
  name: 'Customer Lifetime Value',
  type: 'kpi',
  value: 5000,
  target: 6000,
  unit: 'USD',
})

await api.metrics.record({
  name: 'LTV:CAC Ratio',
  type: 'kpi',
  value: 20,
  target: 30,
  unit: 'ratio',
})

E-commerce Metrics

// Sales metrics
await api.metrics.record({
  name: 'Daily Revenue',
  type: 'gauge',
  value: 45000,
  unit: 'USD',
  timestamp: new Date().toISOString(),
})

await api.metrics.record({
  name: 'Total Orders',
  type: 'counter',
  value: 523,
  unit: 'orders',
})

await api.metrics.record({
  name: 'Average Order Value',
  type: 'kpi',
  value: 86.05,
  target: 100,
  unit: 'USD',
})

// Conversion metrics
await api.metrics.record({
  name: 'Conversion Rate',
  type: 'kpi',
  value: 0.035,
  target: 0.05,
  unit: 'percentage',
})

await api.metrics.record({
  name: 'Cart Abandonment Rate',
  type: 'kpi',
  value: 0.68,
  target: 0.5,
  unit: 'percentage',
})

// Inventory metrics
await api.metrics.record({
  name: 'Out of Stock Items',
  type: 'gauge',
  value: 12,
  unit: 'items',
})

await api.metrics.record({
  name: 'Inventory Turnover',
  type: 'kpi',
  value: 8.5,
  target: 10,
  unit: 'ratio',
})

Marketing Metrics

// Campaign metrics
await api.metrics.record({
  name: 'Campaign ROI',
  type: 'kpi',
  value: 3.5,
  target: 4.0,
  unit: 'ratio',
  metadata: {
    campaign: 'Q4-product-launch',
    spend: 50000,
    revenue: 175000,
  },
})

await api.metrics.record({
  name: 'Cost Per Lead',
  type: 'kpi',
  value: 45,
  target: 35,
  unit: 'USD',
})

await api.metrics.record({
  name: 'Lead Conversion Rate',
  type: 'kpi',
  value: 0.15,
  target: 0.2,
  unit: 'percentage',
})

// Content metrics
await api.metrics.record({
  name: 'Website Traffic',
  type: 'gauge',
  value: 125000,
  unit: 'visitors',
})

await api.metrics.record({
  name: 'Organic Search Traffic',
  type: 'gauge',
  value: 45000,
  unit: 'visitors',
})

await api.metrics.record({
  name: 'Email Open Rate',
  type: 'kpi',
  value: 0.28,
  target: 0.35,
  unit: 'percentage',
})

await api.metrics.record({
  name: 'Email Click Rate',
  type: 'kpi',
  value: 0.05,
  target: 0.08,
  unit: 'percentage',
})

Engineering Metrics

// Performance metrics
await api.metrics.record({
  name: 'API Response Time (P95)',
  type: 'kpi',
  value: 250,
  target: 200,
  unit: 'milliseconds',
})

await api.metrics.record({
  name: 'Error Rate',
  type: 'kpi',
  value: 0.002,
  target: 0.001,
  unit: 'percentage',
})

await api.metrics.record({
  name: 'Uptime',
  type: 'kpi',
  value: 0.9985,
  target: 0.999,
  unit: 'percentage',
})

// Development metrics
await api.metrics.record({
  name: 'Deployment Frequency',
  type: 'kpi',
  value: 12,
  target: 20,
  unit: 'deployments',
  metadata: {
    period: 'weekly',
  },
})

await api.metrics.record({
  name: 'Lead Time for Changes',
  type: 'kpi',
  value: 2.5,
  target: 1,
  unit: 'days',
})

await api.metrics.record({
  name: 'Mean Time to Recovery',
  type: 'kpi',
  value: 45,
  target: 30,
  unit: 'minutes',
})

await api.metrics.record({
  name: 'Change Failure Rate',
  type: 'kpi',
  value: 0.08,
  target: 0.05,
  unit: 'percentage',
})

Metric Aggregation

Time-Series Aggregation

async function aggregateMetrics(metricName: string, period: 'day' | 'week' | 'month') {
  const metrics = await api.metrics.list()

  // Filter by name
  const filtered = metrics.filter((m) => m.name === metricName)

  // Group by period
  const grouped = filtered.reduce(
    (acc, metric) => {
      const date = new Date(metric.timestamp)
      let key: string

      if (period === 'day') {
        key = date.toISOString().split('T')[0]
      } else if (period === 'week') {
        const weekStart = new Date(date)
        weekStart.setDate(date.getDate() - date.getDay())
        key = weekStart.toISOString().split('T')[0]
      } else {
        key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`
      }

      if (!acc[key]) acc[key] = []
      acc[key].push(Number(metric.value))
      return acc
    },
    {} as Record<string, number[]>
  )

  // Calculate aggregates
  return Object.entries(grouped).map(([period, values]) => ({
    period,
    count: values.length,
    sum: values.reduce((a, b) => a + b, 0),
    avg: values.reduce((a, b) => a + b, 0) / values.length,
    min: Math.min(...values),
    max: Math.max(...values),
  }))
}

// Use it
const dailyRevenue = await aggregateMetrics('Daily Revenue', 'day')
console.log('Daily Revenue:', dailyRevenue)

KPI Dashboard

async function getKPIDashboard() {
  const metrics = await api.metrics.list()
  const kpis = metrics.filter((m) => m.type === 'kpi')

  return kpis.map((kpi) => {
    const value = Number(kpi.value)
    const target = Number(kpi.target)
    const progress = target ? (value / target) * 100 : null

    return {
      name: kpi.name,
      value,
      target,
      unit: kpi.unit,
      progress,
      status: progress >= 100 ? 'on-track' : progress >= 75 ? 'at-risk' : 'off-track',
      timestamp: kpi.timestamp,
    }
  })
}

// Use it
const dashboard = await getKPIDashboard()
dashboard.forEach((kpi) => {
  console.log(`${kpi.name}: ${kpi.value}${kpi.unit} / ${kpi.target}${kpi.unit}`)
  console.log(`  Progress: ${kpi.progress?.toFixed(1)}% (${kpi.status})`)
})

OKR Tracking

async function trackOKRs(quarter: string) {
  const metrics = await api.metrics.list()

  const okrs = metrics.filter((m) => m.type === 'okr' && m.metadata?.quarter === quarter)

  // Group by objective
  const byObjective = okrs.reduce(
    (acc, okr) => {
      const objective = okr.metadata?.objective || 'Unknown'

      if (!acc[objective]) {
        acc[objective] = []
      }

      acc[objective].push({
        keyResult: okr.metadata?.keyResult || okr.name,
        value: Number(okr.value),
        target: Number(okr.target),
        progress: (Number(okr.value) / Number(okr.target)) * 100,
        unit: okr.unit,
      })

      return acc
    },
    {} as Record<string, any[]>
  )

  // Calculate objective progress
  return Object.entries(byObjective).map(([objective, keyResults]) => {
    const avgProgress = keyResults.reduce((sum, kr) => sum + kr.progress, 0) / keyResults.length

    return {
      objective,
      keyResults,
      overallProgress: avgProgress,
      status: avgProgress >= 70 ? 'on-track' : avgProgress >= 40 ? 'at-risk' : 'off-track',
    }
  })
}

// Use it
const q4okrs = await trackOKRs('Q4-2024')
q4okrs.forEach((obj) => {
  console.log(`\n${obj.objective} (${obj.overallProgress.toFixed(1)}% - ${obj.status})`)
  obj.keyResults.forEach((kr) => {
    console.log(`  ${kr.keyResult}: ${kr.value} / ${kr.target} (${kr.progress.toFixed(1)}%)`)
  })
})

Best Practices

1. Use Descriptive Names

// ✅ Good - clear names
await api.metrics.record({
  name: 'Monthly Recurring Revenue',
  type: 'kpi',
  value: 125000,
})

// ❌ Avoid - abbreviations
await api.metrics.record({
  name: 'MRR',
  type: 'kpi',
  value: 125000,
})

2. Include Units

// ✅ Good - unit specified
await api.metrics.record({
  name: 'Response Time',
  type: 'kpi',
  value: 250,
  unit: 'milliseconds',
})

// ❌ Avoid - no unit
await api.metrics.record({
  name: 'Response Time',
  type: 'kpi',
  value: 250,
})

3. Set Realistic Targets

// ✅ Good - achievable target
await api.metrics.record({
  name: 'Conversion Rate',
  type: 'kpi',
  value: 0.03,
  target: 0.05, // +67% improvement
  unit: 'percentage',
})

// ❌ Avoid - unrealistic target
await api.metrics.record({
  name: 'Conversion Rate',
  type: 'kpi',
  value: 0.03,
  target: 0.5, // +1567% improvement
  unit: 'percentage',
})
// Record metrics regularly for trend analysis
async function trackDailyMetrics() {
  const timestamp = new Date().toISOString()

  await api.metrics.record({
    name: 'Daily Active Users',
    type: 'gauge',
    value: await getDailyActiveUsers(),
    timestamp,
  })

  await api.metrics.record({
    name: 'Daily Revenue',
    type: 'gauge',
    value: await getDailyRevenue(),
    unit: 'USD',
    timestamp,
  })
}

// Run daily
setInterval(trackDailyMetrics, 86400000)

Next Steps