> ## Documentation Index
> Fetch the complete documentation index at: https://docs.elasticfunnels.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Analytics

> Retrieve analytics metrics and performance data

## Get Available Metrics

Retrieve the list of available metrics you can track.

<ParamField path="brand" type="string" required>
  The brand/project ID
</ParamField>

<ParamField query="split_test_id" type="string">
  Filter metrics relevant to split tests (optional)
</ParamField>

```bash Request theme={null}
GET /api/brands/{brand}/analytics/metrics
```

```bash cURL theme={null}
curl https://app.elasticfunnels.io/api/brands/{brand_id}/analytics/metrics \
  -H "EF-Access-Key: your_api_key_here"
```

<ResponseExample>
  ```json Response theme={null}
  {
    "revenue": {
      "type": "revenue",
      "name": "Revenue",
      "base": "revenue",
      "color": "#10b981",
      "icon": "<svg>...</svg>",
      "info": "Total revenue from orders",
      "group_name": "Sales",
      "modules": ["conversions"]
    },
    "sales": {
      "type": "sales",
      "name": "Sales",
      "base": "sales",
      "color": "#3b82f6",
      "group_name": "Sales",
      "modules": ["conversions"]
    },
    "page_views": {
      "type": "page_views",
      "name": "Page Views",
      "base": "page_views",
      "group_name": "Traffic",
      "modules": ["tracking"]
    }
  }
  ```
</ResponseExample>

***

## Get Metrics Data

Retrieve actual metrics values for a date range.

<ParamField path="brand" type="string" required>
  The brand/project ID
</ParamField>

<ParamField query="start" type="string" required>
  Start date (ISO 8601 format)
</ParamField>

<ParamField query="end" type="string" required>
  End date (ISO 8601 format)
</ParamField>

<ParamField query="tz" type="string">
  Timezone (e.g., "America/New\_York")
</ParamField>

<ParamField query="selected_metrics" type="array">
  Array of metric keys to retrieve
</ParamField>

<ParamField query="filter[field]" type="string">
  Filter by specific field values (e.g., `filter[aff_id]=123`)
</ParamField>

<ParamField query="page_id" type="string">
  Filter by specific page
</ParamField>

<ParamField query="split_test_id" type="string">
  Filter by specific split test
</ParamField>

<ParamField query="engine" type="string">
  Optional. Only use when your integration or account documentation specifies a value.
</ParamField>

```bash Request theme={null}
GET /api/brands/{brand}/analytics/metrics/data
```

```bash cURL theme={null}
curl "https://app.elasticfunnels.io/api/brands/{brand_id}/analytics/metrics/data?start=2024-12-01T00:00:00Z&end=2024-12-10T23:59:59Z&selected_metrics[]=revenue&selected_metrics[]=sales&selected_metrics[]=page_views" \
  -H "EF-Access-Key: your_api_key_here"
```

<ResponseExample>
  ```json Response theme={null}
  {
    "revenue": {
      "value": 15750.00,
      "formatted_value": "$15,750.00",
      "previous_value": 12300.00,
      "change": 28.05,
      "change_symbol": "+",
      "current_range": "Dec 1 - Dec 10",
      "previous_range": "Nov 20 - Nov 30",
      "previous_range_label": "Previous Period",
      "lower_is_better": false,
      "neutral": false
    },
    "sales": {
      "value": 315,
      "formatted_value": "315",
      "previous_value": 246,
      "change": 28.05,
      "change_symbol": "+",
      "lower_is_better": false
    },
    "page_views": {
      "value": 10500,
      "formatted_value": "10,500",
      "previous_value": 8750,
      "change": 20.00,
      "change_symbol": "+"
    }
  }
  ```
</ResponseExample>

***

## Get Analytics Cards

For the full card catalog (batch vs per-card URLs, subscription analytics, split-test charts), see **[Analytics dashboard cards](/api-reference/endpoints/analytics-cards)**.

Retrieve specialized analytics cards data (video analytics, fulfillment metrics, etc.).

<ParamField path="brand" type="string" required>
  The brand/project ID
</ParamField>

<ParamField query="start" type="string" required>
  Start date (ISO 8601 format)
</ParamField>

<ParamField query="end" type="string" required>
  End date (ISO 8601 format)
</ParamField>

<ParamField query="enabled_cards" type="array">
  Array of card types to retrieve
</ParamField>

```bash Request theme={null}
GET /api/brands/{brand}/analytics/metrics/cards
```

```bash cURL theme={null}
curl "https://app.elasticfunnels.io/api/brands/{brand_id}/analytics/metrics/cards?start=2024-12-01T00:00:00Z&end=2024-12-10T23:59:59Z&enabled_cards[]=video_play_rate&enabled_cards[]=time_on_page_before_purchase" \
  -H "EF-Access-Key: your_api_key_here"
```

<ResponseExample>
  ```json Response theme={null}
  {
    "cards": {
      "video_analytics": {
        "video_play_rate": {
          "value": 0.65,
          "formatted_value": "65%"
        },
        "average_video_watch_time": {
          "value": 185.5,
          "formatted_value": "3:05"
        }
      },
      "advanced_metrics": {
        "time_on_page_before_purchase": {
          "value": 320,
          "formatted": "5:20",
          "sample_size": 315
        }
      }
    },
    "enabled_cards": ["video_play_rate", "time_on_page_before_purchase"],
    "filters_applied": {
      "date_range": ["2024-12-01T00:00:00Z", "2024-12-10T23:59:59Z"],
      "page_id": null,
      "split_test_id": null
    }
  }
  ```
</ResponseExample>

***

## Get Grouped Metrics

Retrieve metrics grouped by a specific field (e.g., by product, page, affiliate).

<ParamField path="brand" type="string" required>
  The brand/project ID
</ParamField>

<ParamField path="field" type="string" required>
  Grouping field: `product`, `page`, `aff_id`, `day`, `hour`, `country`, `device`, `utm_source`, etc.
</ParamField>

<ParamField query="start" type="string" required>
  Start date (ISO 8601 format)
</ParamField>

<ParamField query="end" type="string" required>
  End date (ISO 8601 format)
</ParamField>

<ParamField query="selected_metrics" type="array">
  Array of metric keys to retrieve
</ParamField>

```bash Request theme={null}
GET /api/brands/{brand}/analytics/metrics/{field}/data
```

```bash cURL theme={null}
curl "https://app.elasticfunnels.io/api/brands/{brand_id}/analytics/metrics/product/data?start=2024-12-01T00:00:00Z&end=2024-12-10T23:59:59Z&selected_metrics[]=revenue&selected_metrics[]=sales" \
  -H "EF-Access-Key: your_api_key_here"
```

<ResponseExample>
  ```json Response theme={null}
  [
    {
      "row_key": "PROD-001",
      "row_name": "Main Product",
      "revenue": {
        "value": 9875.00,
        "formatted_value": "$9,875.00"
      },
      "sales": {
        "value": 198,
        "formatted_value": "198"
      }
    },
    {
      "row_key": "PROD-002",
      "row_name": "Upsell Product",
      "revenue": {
        "value": 5875.00,
        "formatted_value": "$5,875.00"
      },
      "sales": {
        "value": 117,
        "formatted_value": "117"
      }
    }
  ]
  ```
</ResponseExample>

***

## Export Grouped Metrics

Export grouped metrics to CSV or Excel.

<ParamField path="brand" type="string" required>
  The brand/project ID
</ParamField>

<ParamField path="field" type="string" required>
  Grouping field
</ParamField>

<ParamField body="metrics" type="array">
  Array of metric keys to export
</ParamField>

<ParamField body="format" type="string">
  Export format: `csv` or `excel` (default: `csv`)
</ParamField>

<ParamField body="date_range" type="object">
  Date range object with start/end dates
</ParamField>

```bash Request theme={null}
POST /api/brands/{brand}/analytics/metrics/{field}/export
```

```bash cURL theme={null}
curl -X POST "https://app.elasticfunnels.io/api/brands/{brand_id}/analytics/metrics/product/export" \
  -H "EF-Access-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "metrics": ["revenue", "sales", "aov"],
    "format": "csv",
    "date_range": {
      "start": "2024-12-01",
      "end": "2024-12-10"
    }
  }'
```

<ResponseExample>
  ```json Response theme={null}
  {
    "message": "Export has been queued. You will receive an email when it's ready.",
    "status": "queued",
    "field": "product"
  }
  ```
</ResponseExample>

***

## Available Grouping Fields

<AccordionGroup>
  <Accordion title="Time & Date">
    * `hour` - Hour of day (0-23)
    * `day` - Calendar day
    * `week` - Week number
    * `month` - Month
    * `year` - Year
    * `hour_of_day` - Time grouping
  </Accordion>

  <Accordion title="Business">
    * `aff_id` - Affiliate (requires permission)
    * `subid` - Sub ID
    * `merchant_id` - Merchant
    * `page` - Landing page
    * `product` - Product
    * `funnel_id` - Funnel
  </Accordion>

  <Accordion title="Geography">
    * `country` - Visitor country
    * `region` - Visitor region
    * `shipping_country` - Shipping destination
    * `shipping_state` - Shipping state
  </Accordion>

  <Accordion title="Technology">
    * `device` - Device type (desktop/mobile/tablet)
    * `os` - Operating system
    * `browser` - Browser type
    * `screen_resolution` - Screen size
    * `language` - Browser language
  </Accordion>

  <Accordion title="Marketing">
    * `utm_source` - Traffic source
    * `utm_medium` - Marketing medium
    * `utm_campaign` - Campaign
    * `utm_term` - Keyword/term
    * `utm_content` - Ad content
    * `referrer` - Referring website
  </Accordion>
</AccordionGroup>

***

## Compound Grouping

You can group by multiple fields simultaneously using semicolon separation:

```bash theme={null}
GET /api/brands/{brand}/analytics/metrics/product;page/data
```

This groups metrics by both product AND page.

***

## Filtering

Apply filters using the `filter[field]` query parameter:

```bash theme={null}
# Filter by affiliate
GET /api/brands/{brand}/analytics/metrics/data?filter[aff_id]=123

# Filter by device
GET /api/brands/{brand}/analytics/metrics/data?filter[device]=mobile

# Filter by country
GET /api/brands/{brand}/analytics/metrics/data?filter[country]=US

# Multiple filters
GET /api/brands/{brand}/analytics/metrics/data?filter[device]=mobile&filter[country]=US
```

***

## Custom Metrics

You can create custom metrics using formulas:

```bash cURL theme={null}
curl "https://app.elasticfunnels.io/api/brands/{brand_id}/analytics/metrics/data?start=2024-12-01T00:00:00Z&end=2024-12-10T23:59:59Z&selected_metrics[]=metric_0" \
  -H "EF-Access-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": {
      "0": {
        "name": "Profit Margin",
        "formula": "($revenue - $cogs - $ad_spend) / $revenue * 100",
        "as": "pct"
      }
    }
  }'
```

Custom metric formulas support:

* Basic math operators: `+`, `-`, `*`, `/`, `()`
* Variables: `$metric_name` (e.g., `$revenue`, `$sales`)
* Format types: `currency`, `pct` (percentage), `time`, `number`

***

## Common Metrics

| Metric            | Description           | Module Required           |
| ----------------- | --------------------- | ------------------------- |
| `revenue`         | Total revenue         | conversions               |
| `sales`           | Number of orders      | conversions               |
| `aov`             | Average order value   | conversions               |
| `conversion_rate` | Conversion percentage | conversions, tracking     |
| `page_views`      | Total page views      | tracking                  |
| `sessions`        | Unique sessions       | tracking                  |
| `engagement_rate` | User engagement       | tracking                  |
| `time_on_page`    | Avg time on page      | tracking                  |
| `ad_spend`        | Advertising cost      | integrations              |
| `roas`            | Return on ad spend    | conversions, integrations |
| `cogs`            | Cost of goods sold    | conversions               |
| `net_revenue`     | Revenue minus costs   | conversions               |

***

## Notes

<Info>
  * All dates should be in ISO 8601 format
  * The system automatically compares current period with previous period of equal length
  * Some metrics require specific modules to be enabled
  * Permission-restricted metrics (like `aff_id`) require appropriate user permissions
  * Analytics storage may vary by brand configuration
</Info>

<Warning>
  When grouping by `aff_id`, ensure your API key's user has the `affiliates.view` permission
</Warning>

***

## UTM Performance

Break down conversions and revenue by a single UTM dimension across a date range.

```
GET /api/brands/{brand}/utm-performance/{type}
```

<ParamField path="brand" type="string" required>
  The brand/project ID
</ParamField>

<ParamField path="type" type="string" required>
  UTM dimension: `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`
</ParamField>

<ParamField query="start" type="string" required>
  Start date (ISO 8601)
</ParamField>

<ParamField query="end" type="string" required>
  End date (ISO 8601)
</ParamField>

<ParamField query="tz" type="string">
  Timezone (e.g. `America/New_York`)
</ParamField>

```bash cURL theme={null}
curl "https://app.elasticfunnels.io/api/brands/{brand_id}/utm-performance/utm_source?start=2024-12-01T00:00:00Z&end=2024-12-10T23:59:59Z" \
  -H "EF-Access-Key: your_api_key_here"
```

<ResponseExample>
  ```json Response theme={null}
  [
    { "utm_source": "facebook", "revenue": 9200.00, "sales": 184, "aov": 50.00, "conversion_rate": 0.038, "page_views": 4842 },
    { "utm_source": "google",   "revenue": 4100.00, "sales": 82,  "aov": 50.00, "conversion_rate": 0.041, "page_views": 2000 }
  ]
  ```
</ResponseExample>

***

## Specific Analytics Cards

Individual endpoints for specialised analytics data. All accept `start` and `end` (ISO 8601) query params.

### Time Before First Purchase

How long visitors waited before converting — useful for identifying checkout hesitation.

```
GET /api/brands/{brand}/analytics/metrics/time-before-first-purchase
```

<ResponseExample>
  ```json Response theme={null}
  {
    "buckets": [
      { "label": "< 1 min",   "count": 92,  "pct": 0.29 },
      { "label": "1–5 min",   "count": 118, "pct": 0.37 },
      { "label": "5–15 min",  "count": 64,  "pct": 0.20 },
      { "label": "15–60 min", "count": 30,  "pct": 0.10 },
      { "label": "> 1 hour",  "count": 11,  "pct": 0.04 }
    ],
    "median_seconds": 187,
    "sample_size": 315
  }
  ```
</ResponseExample>

### Add-to-Carts by Video Watch Time

Identifies at which point in a video visitors add to cart — use to find optimal CTA placement.

```
GET /api/brands/{brand}/analytics/metrics/add-to-carts-by-video-time
```

<ResponseExample>
  ```json Response theme={null}
  {
    "buckets": [
      { "video_pct": 0,   "atcs": 12 },
      { "video_pct": 25,  "atcs": 31 },
      { "video_pct": 50,  "atcs": 54 },
      { "video_pct": 75,  "atcs": 29 },
      { "video_pct": 100, "atcs": 8 }
    ]
  }
  ```
</ResponseExample>

### Customer Gender Distribution

```
GET /api/brands/{brand}/analytics/metrics/customer-gender
```

<ResponseExample>
  ```json Response theme={null}
  {
    "male":    { "count": 182, "pct": 0.58 },
    "female":  { "count": 121, "pct": 0.38 },
    "unknown": { "count": 12,  "pct": 0.04 }
  }
  ```
</ResponseExample>

### Video Completion by Gender

```
GET /api/brands/{brand}/analytics/metrics/video-completion-by-gender
```

<ResponseExample>
  ```json Response theme={null}
  {
    "male":   { "avg_completion_pct": 64, "sample": 182 },
    "female": { "avg_completion_pct": 71, "sample": 121 }
  }
  ```
</ResponseExample>

### Products by Pages

Conversion performance broken down by page → product pair.

```
GET /api/brands/{brand}/analytics/metrics/products-by-pages/data
GET /api/brands/{brand}/analytics/metrics/products-by-pages/summary
```

<ResponseExample>
  ```json data response theme={null}
  [
    {
      "page_id": 101, "page_title": "Nutra Landing",
      "product_id": 5, "product_title": "1 Bottle",
      "revenue": 4600.00, "sales": 92, "conversion_rate": 0.038
    }
  ]
  ```
</ResponseExample>

### Upsell Take Rate

```
GET /api/brands/{brand}/analytics/metrics/upsell-take-rate/summary
```

<ResponseExample>
  ```json Response theme={null}
  {
    "upsells": [
      { "product_id": 8, "product_title": "3-Bottle Bundle", "shown": 315, "taken": 87, "take_rate": 0.276, "revenue": 7830.00 }
    ]
  }
  ```
</ResponseExample>

### Units Sold

```
GET /api/brands/{brand}/analytics/metrics/units-sold/summary
```

<ResponseExample>
  ```json Response theme={null}
  {
    "total_units": 847,
    "by_product": [
      { "product_id": 5, "title": "1 Bottle",   "units": 315 },
      { "product_id": 6, "title": "3 Bottles",  "units": 532 }
    ]
  }
  ```
</ResponseExample>

***

## Report Builder

Build, save, and export custom cross-dimensional analytics reports.

### Generate Report

```
POST /api/brands/{brand}/analytics/reports/generate
```

<ParamField body="group_by" type="array" required>
  Dimension keys to group by (e.g. `["product", "utm_source"]`). See [grouping fields](#available-grouping-fields).
</ParamField>

<ParamField body="metrics" type="array" required>
  Metric keys (e.g. `["revenue", "sales", "conversion_rate"]`)
</ParamField>

<ParamField body="start" type="string" required>
  Start date (ISO 8601)
</ParamField>

<ParamField body="end" type="string" required>
  End date (ISO 8601)
</ParamField>

<ParamField body="filters" type="object">
  Key-value filters (e.g. `{"device": "mobile", "country": "US"}`)
</ParamField>

<ParamField body="limit" type="number">
  Max rows returned (default: 100)
</ParamField>

```bash cURL theme={null}
curl -X POST "https://app.elasticfunnels.io/api/brands/{brand_id}/analytics/reports/generate" \
  -H "EF-Access-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "group_by": ["utm_source", "product"],
    "metrics": ["revenue", "sales", "conversion_rate"],
    "start": "2024-12-01T00:00:00Z",
    "end": "2024-12-10T23:59:59Z",
    "filters": {"device": "mobile"},
    "limit": 50
  }'
```

<ResponseExample>
  ```json Response theme={null}
  {
    "rows": [
      {
        "utm_source": "facebook",
        "product": "1 Bottle",
        "revenue": { "value": 4600.00, "formatted_value": "$4,600.00" },
        "sales": { "value": 92, "formatted_value": "92" },
        "conversion_rate": { "value": 0.038, "formatted_value": "3.8%" }
      }
    ],
    "total_rows": 14,
    "truncated": false
  }
  ```
</ResponseExample>

### Get Available Grouping Fields (Report Builder)

```
GET /api/brands/{brand}/analytics/reports/grouping-fields
```

### Get Reporting Periods

```
GET /api/brands/{brand}/analytics/reports/reporting-periods
```

Returns available pre-set periods: `today`, `yesterday`, `last_7_days`, `last_30_days`, `this_month`, `last_month`, etc.

### Save Report

```
POST /api/brands/{brand}/analytics/reports/save
```

<ParamField body="name" type="string" required>
  Report name
</ParamField>

<ParamField body="config" type="object" required>
  Same body as `generate` — stored and re-runnable on demand.
</ParamField>

### List Saved Reports

```
GET /api/brands/{brand}/analytics/reports/saved
```

### Load Saved Report

```
GET /api/brands/{brand}/analytics/reports/saved/{reportId}
```

### Export Saved Report

```
POST /api/brands/{brand}/analytics/reports/saved/{reportId}/export
```

### Delete Saved Report

```
DELETE /api/brands/{brand}/analytics/reports/saved/{reportId}
```

### Export Current Report

```
POST /api/brands/{brand}/analytics/reports/export
```

<ParamField body="format" type="string">
  `csv` (default) or `excel`
</ParamField>

Other body fields same as Generate. Queues an export job and emails a download link when complete.

<ResponseExample>
  ```json 200 Queued theme={null}
  {
    "message": "Export has been queued. You will receive an email when it's ready.",
    "status": "queued"
  }
  ```
</ResponseExample>

***

## Analytics Segments

Create and manage reusable audience segments for filtering reports.

### List Segments

```
GET /api/brands/{brand}/analytics/segments
```

### Get Segment

```
GET /api/brands/{brand}/analytics/segments/{segment}
```

### Create Segment

```
POST /api/brands/{brand}/analytics/segments
```

<ParamField body="name" type="string" required>
  Segment name
</ParamField>

<ParamField body="conditions" type="array" required>
  Array of condition objects. Each has `field`, `operator` (`eq`, `neq`, `gte`, `lte`, `in`), and `value`.
</ParamField>

<ParamField body="operator" type="string">
  How conditions combine: `and` (default) or `or`
</ParamField>

```bash cURL theme={null}
curl -X POST "https://app.elasticfunnels.io/api/brands/{brand_id}/analytics/segments" \
  -H "EF-Access-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "High-Value Mobile Buyers",
    "operator": "and",
    "conditions": [
      { "field": "device",  "operator": "eq",  "value": "mobile" },
      { "field": "revenue", "operator": "gte", "value": 100 }
    ]
  }'
```

<ResponseExample>
  ```json 200 Created theme={null}
  {
    "id": 4,
    "name": "High-Value Mobile Buyers",
    "operator": "and",
    "conditions": [
      { "field": "device",  "operator": "eq",  "value": "mobile" },
      { "field": "revenue", "operator": "gte", "value": 100 }
    ],
    "brand_id": 42,
    "created_at": "2024-12-11T09:00:00.000000Z"
  }
  ```
</ResponseExample>

### Update Segment

```
PUT /api/brands/{brand}/analytics/segments/{segment}
```

### Delete Segment

```
DELETE /api/brands/{brand}/analytics/segments/{segment}
```

### Preview Segment

Run a segment definition against live data without saving it.

```
POST /api/brands/{brand}/analytics/segments/preview
```

Body: same as Create.

<ResponseExample>
  ```json Preview response theme={null}
  {
    "count": 487,
    "sample": [
      { "session_id": "abc123", "revenue": 147.00, "device": "mobile" }
    ]
  }
  ```
</ResponseExample>

### Install Default Segments

```
POST /api/brands/{brand}/analytics/segments/install-defaults
```

Installs a curated starter set (e.g. "New Buyers", "Repeat Customers", "Abandoned Carts").
