npm package: @opencommerceprotocol/analytics
Description: Open Commerce Protocol — Analytics server for merchant visibility into AI agent interactions
Latest version: 1.0.0

# @opencommerceprotocol/analytics

Analytics server for the [Open Commerce Protocol](https://opencommerceprotocol.org). Tracks AI agent interactions with your OCP store — tool calls, checkout events, widget usage, and LLM tier distribution. Privacy-first, opt-in, no PII collected.

## Installation

```bash
npm install @opencommerceprotocol/analytics
```

## Quick Start

### Run the analytics server

```bash
# With environment variables
OCP_ANALYTICS_PORT=3100 OCP_ANALYTICS_DB=./analytics.db npx tsx src/index.ts

# Or import in your application
```

### Embed in your application

```typescript
import { createApp } from '@opencommerceprotocol/analytics';
import { serve } from '@hono/node-server';

const { app, repo } = createApp('./ocp-analytics.db');

serve({ fetch: app.fetch, port: 3100 });
console.log('OCP Analytics running at http://localhost:3100');
```

## `createApp(dbPath?)`

Returns `{ app: Hono, repo: SQLiteEventRepository }`.

| Parameter | Default | Description |
|-----------|---------|-------------|
| `dbPath` | `':memory:'` | SQLite database file path |

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `OCP_ANALYTICS_PORT` | `3100` | HTTP server port |
| `OCP_ANALYTICS_DB` | `./ocp-analytics.db` | SQLite database path |

## API Endpoints

### `POST /v1/events` — Ingest events

No authentication required. Rate-limited to prevent abuse.

```bash
curl -X POST http://localhost:3100/v1/events \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "type": "tool_call",
        "timestamp": "2026-03-01T12:00:00Z",
        "merchant_url": "https://mystore.com",
        "tool": "search_products",
        "duration_ms": 45,
        "success": true,
        "tier": "regex"
      }
    ]
  }'
```

### `GET /v1/stats/summary` — Merchant summary

Requires API key in `Authorization: Bearer <key>` header.

```bash
curl http://localhost:3100/v1/stats/summary?merchant_url=https://mystore.com&period=7d \
  -H "Authorization: Bearer your-api-key"
```

Response:
```json
{
  "merchant_url": "https://mystore.com",
  "period": "7d",
  "total_events": 1234,
  "unique_sessions": 89,
  "tool_calls": 456,
  "top_tools": [
    { "tool": "search_products", "count": 234 },
    { "tool": "get_product", "count": 123 }
  ],
  "tier_distribution": { "regex": 0.6, "browser_llm": 0.3, "cloud_llm": 0.1 },
  "checkout_conversion": 0.12
}
```

### `GET /v1/stats/tools` — Per-tool breakdown

```bash
curl "http://localhost:3100/v1/stats/tools?merchant_url=https://mystore.com" \
  -H "Authorization: Bearer your-api-key"
```

### `GET /v1/stats/timeline` — Time-series data

```bash
curl "http://localhost:3100/v1/stats/timeline?merchant_url=https://mystore.com&granularity=day" \
  -H "Authorization: Bearer your-api-key"
```

### `GET /health` — Health check

```bash
curl http://localhost:3100/health
# { "status": "ok" }
```

## `SQLiteEventRepository`

Access the event storage directly:

```typescript
import { SQLiteEventRepository } from '@opencommerceprotocol/analytics';

const repo = new SQLiteEventRepository('./analytics.db');

// Query stats
const summary = await repo.getMerchantStats('https://mystore.com', '7d');
const tools = await repo.getToolStats('https://mystore.com', '30d');
const timeline = await repo.getTimeline('https://mystore.com', 'day', 30);
```

## Authentication Middleware

```typescript
import { apiKeyAuth } from '@opencommerceprotocol/analytics';
import { Hono } from 'hono';

const app = new Hono();
// Protect specific routes
app.use('/admin/*', apiKeyAuth());
```

Set API keys via `OCP_ANALYTICS_API_KEYS` environment variable (comma-separated).

## Event Types

| Event Type | When Triggered |
|-----------|----------------|
| `tool_call` | An OCP tool was called |
| `runtime_init` | OCP runtime initialized on a page |
| `widget_open` | Chat widget opened by user |
| `widget_message` | Message sent in chat widget |
| `llm_tier_used` | Browser LLM or cloud LLM used |
| `checkout_started` | `begin_checkout` tool called |

## `OCPAnalyticsEvent`

```typescript
interface OCPAnalyticsEvent {
  type: OCPEventType;       // event type
  timestamp: string;        // ISO 8601
  merchant_url: string;     // identifies the store
  tool?: string;            // tool name for tool_call events
  duration_ms?: number;     // tool call duration
  success?: boolean;        // tool call result
  tier?: ProcessingTier;    // 'regex' | 'browser_llm' | 'cloud_llm'
  session_id?: string;      // anonymized session (no PII)
  metadata?: Record<string, unknown>;  // additional context
}
```

## Client-Side Collection

The analytics client is built into `@opencommerceprotocol/runtime`. Enable it in `OCP.init()`:

```javascript
OCP.init({
  handlers: { ... },
  analytics: {
    enabled: true,
    endpoint: 'https://analytics.mystore.com/v1/events',
    flushInterval: 5000,
    storageKey: 'ocp_events',
  },
});
```

Or import the collector directly:

```typescript
import { OCPAnalytics } from '@opencommerceprotocol/analytics/client';

const analytics = new OCPAnalytics({
  enabled: true,
  endpoint: 'https://analytics.mystore.com/v1/events',
});

analytics.trackToolCall('search_products', { query: 'headphones' });
```

## Self-Hosting

The analytics server is a standalone Hono application that can be deployed as:

- **Node.js**: `node dist/index.js`
- **Cloudflare Workers**: `wrangler deploy` (adapt to use D1 instead of SQLite)
- **Docker**: Mount the SQLite file as a volume