# Erkmo AI Integration Guide

> Give this document to your AI agent (Claude, GPT, Cursor, etc.) so it knows how to query and manage your Erkmo analytics.

## What is Erkmo

Erkmo is a web and mobile analytics platform that tracks visitors, pageviews, sessions, conversions, and revenue across websites, iOS apps, and Android apps. It provides real-time dashboards, channel attribution, conversion goals, smart alerts, and audience insights. Erkmo offers a REST API and an MCP server so AI agents can programmatically read analytics data, create alerts, and manage conversion goals.

---

## Authentication

All API requests require an API key passed as a Bearer token.

```
Authorization: Bearer erk_...
```

API keys are created in **Settings > API Keys** inside the Erkmo dashboard. Each key has one or more scopes that control access:

| Scope | Description |
|-------|-------------|
| `analytics:read` | Read analytics data (overview, timeseries, pages, sources, audience, realtime) |
| `sites:read` | List accessible sites |
| `alerts:read` | Read alert rules and triggered alert history |
| `alerts:write` | Create, update, and delete alert rules |
| `goals:read` | Read conversion goals |
| `goals:write` | Create, update, and delete conversion goals |

---

## Base URL

```
https://erkmo.com/api/v1
```

All endpoint paths below are relative to this base URL.

---

## REST API Endpoints

### Sites

#### List Sites

```
GET /sites
```

**Required scope:** `sites:read`

**Response:**

```json
{
  "data": [
    {
      "id": "clxyz...",
      "name": "My Website",
      "domain": "example.com",
      "timezone": "America/New_York",
      "isActive": true,
      "createdAt": "2025-01-15T10:30:00.000Z"
    }
  ],
  "meta": {
    "generatedAt": "2025-03-15T12:00:00.000Z"
  }
}
```

---

### Analytics

All analytics endpoints accept these **query parameters**:

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `startDate` | string (YYYY-MM-DD) | 30 days ago | Start of date range |
| `endDate` | string (YYYY-MM-DD) | Today | End of date range |
| `timezone` | string (IANA) | `UTC` | Timezone for date bucketing |

#### Get Analytics Overview

```
GET /sites/{siteId}/analytics/overview
```

**Required scope:** `analytics:read`

**Response:**

```json
{
  "data": {
    "visitors": 12847,
    "pageviews": 48293,
    "sessions": 15420,
    "bounceRate": 42.5,
    "avgDuration": 185,
    "conversions": 385,
    "orders": 120,
    "leads": 200,
    "registrations": 65,
    "revenue": 15000.00,
    "topPages": [
      { "path": "/", "views": 8500, "uniqueVisitors": 6200 }
    ],
    "trafficSources": [
      { "source": "google", "sessions": 6100, "uniqueVisitors": 5400 }
    ]
  },
  "meta": {
    "siteId": "clxyz...",
    "startDate": "2025-02-13",
    "endDate": "2025-03-15",
    "timezone": "UTC",
    "generatedAt": "2025-03-15T12:00:00.000Z"
  }
}
```

#### Get Timeseries

```
GET /sites/{siteId}/analytics/timeseries
```

**Required scope:** `analytics:read`

Returns time-bucketed analytics for trend analysis and charting.

**Response:**

```json
{
  "data": [
    {
      "date": "2025-03-01",
      "visitors": 450,
      "pageviews": 1200,
      "sessions": 520,
      "bounceRate": 0.41,
      "avgDuration": 192,
      "conversions": 15,
      "orders": 3,
      "leads": 5,
      "registrations": 1,
      "revenue": 150.00
    }
  ],
  "meta": {
    "siteId": "clxyz...",
    "startDate": "2025-03-01",
    "endDate": "2025-03-15",
    "timezone": "UTC",
    "generatedAt": "2025-03-15T12:00:00.000Z"
  }
}
```

#### Get Top Pages

```
GET /sites/{siteId}/analytics/pages
```

**Required scope:** `analytics:read`

**Additional query parameters:**

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `limit` | integer | 20 | Max pages to return |

**Response:**

```json
{
  "data": [
    { "path": "/pricing", "views": 3200, "uniqueVisitors": 2800 }
  ],
  "meta": {
    "siteId": "clxyz...",
    "startDate": "2025-02-13",
    "endDate": "2025-03-15",
    "timezone": "UTC",
    "limit": 20,
    "generatedAt": "2025-03-15T12:00:00.000Z"
  }
}
```

#### Get Traffic Sources

```
GET /sites/{siteId}/analytics/sources
```

**Required scope:** `analytics:read`

**Response:**

```json
{
  "data": [
    {
      "source": "google",
      "medium": "organic",
      "campaign": "none",
      "sessions": 6100,
      "uniqueVisitors": 5400,
      "pageviews": 15000,
      "conversions": 195,
      "orders": 50,
      "leads": 100,
      "revenue": 5000.00
    }
  ],
  "meta": {
    "siteId": "clxyz...",
    "startDate": "2025-02-13",
    "endDate": "2025-03-15",
    "timezone": "UTC",
    "generatedAt": "2025-03-15T12:00:00.000Z"
  }
}
```

#### Get Audience

```
GET /sites/{siteId}/analytics/audience
```

**Required scope:** `analytics:read`

**Response:**

```json
{
  "data": {
    "devices": [
      { "device": "desktop", "sessions": 9500, "visitors": 8200, "conversions": 130, "revenue": 4000.00 },
      { "device": "mobile", "sessions": 4800, "visitors": 4100, "conversions": 50, "revenue": 1500.00 }
    ],
    "browsers": [
      { "browser": "Chrome", "sessions": 9000, "visitors": 7800, "conversions": 115, "revenue": 3500.00 }
    ],
    "locations": [
      { "country": "United States", "city": "New York", "sessions": 7800, "visitors": 6500, "conversions": 95, "revenue": 3000.00 }
    ]
  },
  "meta": {
    "siteId": "clxyz...",
    "startDate": "2025-02-13",
    "endDate": "2025-03-15",
    "timezone": "UTC",
    "generatedAt": "2025-03-15T12:00:00.000Z"
  }
}
```

#### Get Realtime

```
GET /sites/{siteId}/analytics/realtime
```

**Required scope:** `analytics:read`

No query parameters required.

**Response:**

```json
{
  "data": {
    "activeUsers": 23,
    "metrics": {
      "visitors": 450,
      "pageviews": 1200,
      "events": 1500
    },
    "topPages": [
      { "path": "/", "views": 85, "uniqueVisitors": 40 },
      { "path": "/pricing", "views": 52, "uniqueVisitors": 25 }
    ],
    "recentActivity": [
      { "event": "pageview", "page": "/blog/post-1", "referrer": "https://google.com", "timestamp": "2025-03-15T12:00:05.000Z" }
    ]
  },
  "meta": {
    "siteId": "clxyz...",
    "generatedAt": "2025-03-15T12:00:06.000Z"
  }
}
```

---

### Alerts

#### List Alerts

```
GET /sites/{siteId}/alerts
```

**Required scope:** `alerts:read`

**Response:**

```json
{
  "data": [
    {
      "id": "clxyz...",
      "siteId": "clxyz...",
      "name": "Traffic spike",
      "type": "metric",
      "metric": "visitors",
      "condition": "above",
      "threshold": 1000,
      "percentage": null,
      "timeWindow": "24hour",
      "sensitivity": null,
      "channels": ["email"],
      "emailRecipients": ["team@example.com"],
      "slackWebhook": null,
      "discordWebhook": null,
      "customWebhook": null,
      "isActive": true,
      "cooldownMinutes": 60,
      "lastTriggered": null,
      "createdAt": "2025-03-01T10:00:00.000Z",
      "updatedAt": "2025-03-01T10:00:00.000Z"
    }
  ],
  "meta": {
    "siteId": "clxyz...",
    "generatedAt": "2025-03-15T12:00:00.000Z"
  }
}
```

#### Create Alert

```
POST /sites/{siteId}/alerts
```

**Required scope:** `alerts:write`

**Request body:**

```json
{
  "name": "Traffic spike",
  "type": "metric",
  "condition": "above",
  "channels": ["email"],
  "metric": "visitors",
  "threshold": 1000,
  "timeWindow": "24hour",
  "cooldownMinutes": 60,
  "emailRecipients": ["team@example.com"]
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Alert name |
| `type` | string | Yes | `metric`, `anomaly`, `threshold`, or `goal` |
| `condition` | string | Yes | `above`, `below`, `equals`, or `changes_by` |
| `channels` | string[] | Yes | Notification channels: `email`, `slack`, `discord`, `webhook` |
| `metric` | string | No | Metric to monitor (e.g. `visitors`, `pageviews`, `bounceRate`) |
| `threshold` | number | No | Threshold value to trigger alert |
| `percentage` | number | No | Percentage change to trigger alert |
| `timeWindow` | string | No | Time window (default: `24hour`) |
| `sensitivity` | string | No | `low`, `medium`, or `high` (for anomaly detection) |
| `emailRecipients` | string[] | No | Email addresses for email channel |
| `slackWebhook` | string | No | Slack webhook URL |
| `discordWebhook` | string | No | Discord webhook URL |
| `customWebhook` | string | No | Custom webhook URL |
| `cooldownMinutes` | number | No | Minutes to wait before re-triggering |

**Response:** `201 Created` — returns the created alert object.

#### Get Alert

```
GET /sites/{siteId}/alerts/{alertId}
```

**Required scope:** `alerts:read`

#### Update Alert

```
PUT /sites/{siteId}/alerts/{alertId}
```

**Required scope:** `alerts:write`

Accepts the same fields as Create Alert (all optional).

#### Delete Alert

```
DELETE /sites/{siteId}/alerts/{alertId}
```

**Required scope:** `alerts:write`

**Response:**

```json
{
  "data": { "deleted": true, "id": "clxyz..." }
}
```

#### Get Alert History

```
GET /sites/{siteId}/alerts/history
```

**Required scope:** `alerts:read`

**Query parameters:**

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `limit` | integer | 50 | Max results to return |

**Response:**

```json
{
  "data": [
    {
      "id": "clxyz...",
      "ruleId": "clxyz...",
      "ruleName": "Traffic spike",
      "siteId": "clxyz...",
      "severity": "warning",
      "title": "Traffic spike triggered",
      "message": "Visitors exceeded 1000 in the last 24 hours",
      "data": {},
      "triggeredAt": "2025-03-14T08:30:00.000Z",
      "acknowledged": false,
      "acknowledgedAt": null,
      "acknowledgedBy": null
    }
  ],
  "meta": {
    "siteId": "clxyz...",
    "limit": 50,
    "generatedAt": "2025-03-15T12:00:00.000Z"
  }
}
```

---

### Goals

#### List Goals

```
GET /sites/{siteId}/goals
```

**Required scope:** `goals:read`

**Response:**

```json
{
  "data": [
    {
      "id": "clxyz...",
      "siteId": "clxyz...",
      "name": "Sign up",
      "description": "User completes signup flow",
      "url_type": "exact",
      "url_value": "/signup/complete",
      "event_name": null,
      "value": 10.0,
      "isActive": true,
      "createdAt": "2025-03-01T10:00:00.000Z",
      "updatedAt": "2025-03-01T10:00:00.000Z"
    }
  ],
  "meta": {
    "siteId": "clxyz...",
    "generatedAt": "2025-03-15T12:00:00.000Z"
  }
}
```

#### Create Goal

```
POST /sites/{siteId}/goals
```

**Required scope:** `goals:write`

**Request body:**

```json
{
  "name": "Sign up",
  "description": "User completes signup flow",
  "url_type": "exact",
  "url_value": "/signup/complete",
  "value": 10.0
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Goal name |
| `description` | string | No | Goal description |
| `url_type` | string | No | URL match type: `exact`, `contains`, or `regex` |
| `url_value` | string | No | URL pattern to match |
| `is_case_sensitive` | boolean | No | Case-sensitive URL matching |
| `event_name` | string | No | Custom event name to match |
| `event_label` | string | No | Event label field to match |
| `event_label_value` | string | No | Event label value |
| `event_category` | string | No | Event category field to match |
| `event_category_value` | string | No | Event category value |
| `event_action` | string | No | Event action field to match |
| `event_action_value` | string | No | Event action value |
| `utm_source` | string | No | UTM source to match |
| `value` | number | No | Monetary value per conversion |

**Response:** `201 Created` — returns the created goal object.

#### Get Goal

```
GET /sites/{siteId}/goals/{goalId}
```

**Required scope:** `goals:read`

#### Update Goal

```
PUT /sites/{siteId}/goals/{goalId}
```

**Required scope:** `goals:write`

Accepts the same fields as Create Goal (all optional), plus:

| Field | Type | Description |
|-------|------|-------------|
| `isActive` | boolean | Enable or disable the goal |

#### Delete Goal

```
DELETE /sites/{siteId}/goals/{goalId}
```

**Required scope:** `goals:write`

**Response:**

```json
{
  "data": { "deleted": true, "id": "clxyz..." }
}
```

### Ads & ROAS

#### Get Ad Performance with True ROAS

```
GET /sites/{siteId}/ads
```

**Required scope:** `analytics:read`

**Query parameters:**

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `days` | number | `30` | Number of days (1-365) |
| `groupBy` | string | `campaign` | Grouping: `platform`, `campaign`, or `adGroup` |

**Response:**

```json
{
  "data": [
    {
      "platform": "google_ads",
      "campaignId": "12345",
      "campaignName": "Brand Campaign",
      "spend": 1500.00,
      "impressions": 50000,
      "clicks": 2000,
      "platformConversions": 50,
      "platformRevenue": 5000.00,
      "trueConversions": 42,
      "trueRevenue": 4200.00,
      "trueRoas": 2.80,
      "trueCpa": 35.71
    }
  ],
  "meta": { "siteId": "...", "days": 30, "groupBy": "campaign" }
}
```

The `trueConversions` and `trueRevenue` fields come from Erkmo's click-to-conversion tracking (matching click IDs like `gclid`/`fbclid` to actual purchases), while `platformConversions` and `platformRevenue` are the values reported by the ad platform itself.

---

## MCP Server

Erkmo exposes an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that AI agents can connect to directly. This gives agents tool-based access to all analytics, alerts, and goals.

### Connection

**SSE endpoint:** `https://erkmo.com/api/mcp/sse`

Authentication uses the same API key as the REST API, passed as a Bearer token in headers.

### Claude Desktop Configuration

Add this to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "erkmo": {
      "url": "https://erkmo.com/api/mcp/sse",
      "headers": {
        "Authorization": "Bearer erk_YOUR_API_KEY"
      }
    }
  }
}
```

### Available Tools (12)

#### Analytics Tools

##### `list_sites`

List all sites accessible to the API key.

**Parameters:** _(none)_

**Response:**

```json
[
  {
    "id": "clxyz...",
    "name": "My Website",
    "domain": "example.com",
    "timezone": "America/New_York",
    "isActive": true,
    "createdAt": "2025-01-15T10:30:00.000Z"
  }
]
```

##### `get_analytics_overview`

Get site analytics summary: visitors, pageviews, bounce rate, session duration, top pages, traffic sources.

**Parameters:** `siteId` (required), `startDate`, `endDate`, `timezone`

**Response:**

```json
{
  "visitors": 12847,
  "pageviews": 48293,
  "sessions": 15420,
  "bounceRate": 42.5,
  "avgDuration": 185,
  "conversions": 385,
  "orders": 120,
  "leads": 200,
  "registrations": 65,
  "revenue": 15000.00,
  "topPages": [
    { "path": "/", "views": 8500, "uniqueVisitors": 6200 }
  ],
  "trafficSources": [
    { "source": "google", "sessions": 6100, "uniqueVisitors": 5400 }
  ]
}
```

##### `get_timeseries`

Get time-bucketed analytics metrics for trend analysis and charting.

**Parameters:** `siteId` (required), `startDate`, `endDate`, `timezone`

**Response:**

```json
[
  {
    "date": "2025-03-01",
    "visitors": 450,
    "pageviews": 1200,
    "sessions": 520,
    "bounceRate": 0.41,
    "avgDuration": 192,
    "conversions": 15,
    "orders": 3,
    "leads": 5,
    "registrations": 1,
    "revenue": 150.00
  }
]
```

##### `get_top_pages`

Get top pages ranked by pageviews.

**Parameters:** `siteId` (required), `limit` (optional, default 20), `startDate`, `endDate`, `timezone`

**Response:**

```json
[
  { "path": "/pricing", "views": 3200, "uniqueVisitors": 2800 }
]
```

##### `get_traffic_sources`

Get traffic sources showing where visitors come from.

**Parameters:** `siteId` (required), `startDate`, `endDate`, `timezone`

**Response:**

```json
[
  {
    "source": "google",
    "medium": "organic",
    "campaign": "none",
    "sessions": 6100,
    "uniqueVisitors": 5400,
    "pageviews": 15000,
    "conversions": 195,
    "orders": 50,
    "leads": 100,
    "revenue": 5000.00
  }
]
```

##### `get_audience`

Get audience breakdown by device, browser, and country.

**Parameters:** `siteId` (required), `startDate`, `endDate`, `timezone`

**Response:**

```json
{
  "devices": [
    { "device": "desktop", "sessions": 9500, "visitors": 8200, "conversions": 130, "revenue": 4000.00 },
    { "device": "mobile", "sessions": 4800, "visitors": 4100, "conversions": 50, "revenue": 1500.00 }
  ],
  "browsers": [
    { "browser": "Chrome", "sessions": 9000, "visitors": 7800, "conversions": 115, "revenue": 3500.00 }
  ],
  "locations": [
    { "country": "United States", "city": "New York", "sessions": 7800, "visitors": 6500, "conversions": 95, "revenue": 3000.00 }
  ]
}
```

##### `get_realtime`

Get real-time active users, active pages, and recent events.

**Parameters:** `siteId` (required)

**Response:**

```json
{
  "activeUsers": 23,
  "metrics": {
    "visitors": 450,
    "pageviews": 1200,
    "events": 1500
  },
  "topPages": [
    { "path": "/", "views": 85, "uniqueVisitors": 40 },
    { "path": "/pricing", "views": 52, "uniqueVisitors": 25 }
  ],
  "recentActivity": [
    { "event": "pageview", "page": "/blog/post-1", "referrer": "https://google.com", "timestamp": "2025-03-15T12:00:05.000Z" }
  ]
}
```

#### Alert Tools

##### `list_alerts`

List all alert rules for a site.

**Parameters:** `siteId` (required)

**Response:**

```json
[
  {
    "id": "clxyz...",
    "siteId": "clxyz...",
    "userId": "clxyz...",
    "name": "Traffic spike",
    "type": "metric",
    "metric": "visitors",
    "condition": "above",
    "threshold": 1000,
    "percentage": null,
    "timeWindow": "24hour",
    "sensitivity": null,
    "channels": ["email"],
    "isActive": true,
    "cooldownMinutes": 60,
    "lastTriggered": null,
    "createdAt": "2025-03-01T10:00:00.000Z",
    "updatedAt": "2025-03-01T10:00:00.000Z"
  }
]
```

##### `create_alert`

Create a new alert rule for a site.

**Parameters:** `siteId`, `name`, `type`, `condition`, `channels` (all required); `metric`, `threshold`, `timeWindow` (optional)

**Response:**

```json
{
  "id": "clxyz...",
  "siteId": "clxyz...",
  "userId": "clxyz...",
  "name": "Traffic spike",
  "type": "metric",
  "metric": "visitors",
  "condition": "above",
  "threshold": 1000,
  "percentage": null,
  "timeWindow": "24hour",
  "sensitivity": null,
  "channels": ["email"],
  "isActive": true,
  "cooldownMinutes": 60,
  "lastTriggered": null,
  "createdAt": "2025-03-15T12:00:00.000Z",
  "updatedAt": "2025-03-15T12:00:00.000Z"
}
```

##### `get_alert_history`

Get history of triggered alerts for a site.

**Parameters:** `siteId` (required), `limit` (optional, default 50)

**Response:**

```json
[
  {
    "id": "clxyz...",
    "ruleId": "clxyz...",
    "ruleName": "Traffic spike",
    "siteId": "clxyz...",
    "severity": "warning",
    "title": "Traffic spike triggered",
    "message": "Visitors exceeded 1000 in the last 24 hours",
    "data": {},
    "triggeredAt": "2025-03-14T08:30:00.000Z",
    "acknowledged": false,
    "acknowledgedAt": null,
    "acknowledgedBy": null
  }
]
```

#### Goal Tools

##### `list_goals`

List all conversion goals for a site.

**Parameters:** `siteId` (required)

**Response:**

```json
[
  {
    "id": "clxyz...",
    "siteId": "clxyz...",
    "name": "Sign up",
    "description": "User completes signup flow",
    "url_type": "exact",
    "url_value": "/signup/complete",
    "event_name": null,
    "value": 10.0,
    "isActive": true,
    "createdAt": "2025-03-01T10:00:00.000Z",
    "updatedAt": "2025-03-01T10:00:00.000Z"
  }
]
```

##### `create_goal`

Create a new conversion goal for a site.

**Parameters:** `siteId`, `name` (required); `description`, `url_type`, `url_value`, `event_name`, `value` (optional)

**Response:**

```json
{
  "id": "clxyz...",
  "siteId": "clxyz...",
  "name": "Sign up",
  "description": "User completes signup flow",
  "url_type": "exact",
  "url_value": "/signup/complete",
  "is_case_sensitive": false,
  "event_name": null,
  "event_label": null,
  "event_label_value": null,
  "event_category": null,
  "event_category_value": null,
  "event_action": null,
  "event_action_value": null,
  "utm_source": null,
  "value": 10.0,
  "isActive": true,
  "createdAt": "2025-03-15T12:00:00.000Z",
  "updatedAt": "2025-03-15T12:00:00.000Z"
}
```

> **Note:** MCP tool responses are returned as JSON text inside MCP content blocks. The examples above show the parsed JSON that your agent will receive.

### MCP Resources

##### `erkmo://sites`

List of all accessible sites. Returns the same format as `list_sites`.

##### `erkmo://sites/{siteId}/summary`

Current analytics summary (overview + realtime) for a site.

**Response:**

```json
{
  "overview": {
    "visitors": 12847,
    "pageviews": 48293,
    "sessions": 15420,
    "bounceRate": 42.5,
    "avgDuration": 185,
    "conversions": 385,
    "orders": 120,
    "leads": 200,
    "revenue": 15000.00,
    "topPages": [
      { "path": "/", "views": 8500, "uniqueVisitors": 6200 }
    ],
    "trafficSources": [
      { "source": "google", "sessions": 6100, "uniqueVisitors": 5400 }
    ]
  },
  "realtime": {
    "activeUsers": 23,
    "metrics": {
      "visitors": 450,
      "pageviews": 1200,
      "events": 1500
    },
    "topPages": [
      { "path": "/", "views": 85, "uniqueVisitors": 40 }
    ],
    "recentActivity": [
      { "event": "pageview", "page": "/blog/post-1", "referrer": "https://google.com", "timestamp": "2025-03-15T12:00:05.000Z" }
    ]
  }
}
```

---

## Response Format

### Success

All successful responses follow this structure:

```json
{
  "data": { ... },
  "meta": {
    "generatedAt": "2025-03-15T12:00:00.000Z"
  }
}
```

- `data` contains the result (object or array).
- `meta` contains request context (siteId, date range, timezone, generatedAt).

### Errors

```json
{
  "error": "Human-readable error message"
}
```

Common HTTP status codes: `400` (bad request), `401` (unauthorized), `403` (forbidden / missing scope), `404` (not found), `500` (server error).

---

## Date Defaults

- If `startDate` is omitted, it defaults to **30 days ago**.
- If `endDate` is omitted, it defaults to **today**.
- Dates should be in **ISO 8601** format: `YYYY-MM-DD`.
- Timezone defaults to `UTC`. Use IANA timezone strings (e.g. `America/New_York`, `Europe/London`).

---

## Example Workflows

### Get last week's traffic

```
1. Call GET /sites to get your siteId
2. Call GET /sites/{siteId}/analytics/overview?startDate=2025-03-08&endDate=2025-03-15
3. Review visitors, pageviews, bounceRate, and topPages in the response
```

### Compare this month vs last month

```
1. Call GET /sites/{siteId}/analytics/overview?startDate=2025-03-01&endDate=2025-03-15
2. Call GET /sites/{siteId}/analytics/overview?startDate=2025-02-01&endDate=2025-02-28
3. Compare visitors, pageviews, bounceRate, and sessionDuration between the two responses
```

### Set up a traffic drop alert

```
1. Call POST /sites/{siteId}/alerts with body:
   {
     "name": "Traffic drop",
     "type": "metric",
     "condition": "below",
     "metric": "visitors",
     "threshold": 100,
     "timeWindow": "24hour",
     "channels": ["email"],
     "emailRecipients": ["you@example.com"]
   }
```

### Track signups as a conversion goal

```
1. Call POST /sites/{siteId}/goals with body:
   {
     "name": "Signup completed",
     "url_type": "exact",
     "url_value": "/signup/complete",
     "value": 25.00
   }
```

### Find your top traffic sources this quarter

```
1. Call GET /sites/{siteId}/analytics/sources?startDate=2025-01-01&endDate=2025-03-31
2. Review the ranked list of sources with visitor counts and conversion rates
```

### Check real-time activity

```
1. Call GET /sites/{siteId}/analytics/realtime
2. See activeUsers count, which pages they're on, and recent events
```
