# External Analytics API

Our External Analytics API lets you pull Humblytics data programmatically — traffic, pages, clicks, forms, and funnels — using the same property-scoped API keys that power the in-app dashboards. This guide covers authentication, required parameters, endpoints, and typical responses.

> **Base URL**: `https://app.humblytics.com/api/external/v1`

## In-App API Access Page

The Humblytics dashboard includes a dedicated **API Access** page (found under **Utilities** in the sidebar) that provides everything you need to get started with the API.

**API Key Generation and Management**

Use the **Generate New Key** button to create a new API key for your property. You can manage existing keys from this page, including revoking keys that are no longer needed. Each key is scoped to a single property.

**Quick Start**

The API Access page displays a Quick Start section with your property-specific details pre-filled:

* **Property ID** -- your unique property identifier
* **Base URL** -- `https://app.humblytics.com/api/external/v1/`
* **Example curl request** -- a ready-to-copy request you can run immediately to verify your setup

**AI Agent Instructions**

The API Access page also includes an **AI Agent Instructions** section with tabs for different AI coding tools:

* **Claude Code** -- copy-paste instructions for integrating the Humblytics API with Claude Code
* **Cursor** -- copy-paste instructions for integrating the Humblytics API with Cursor
* **Generic** -- general-purpose instructions that work with any AI coding assistant

These instructions provide your AI tool with the context it needs to query the Humblytics API on your behalf, including your property ID, API key, and available endpoints.

***

## Authentication

* Generate an API key for your property in the Humblytics app (sidebar → **Utilities** → **API**).
* Include the key in every request using the `Authorization` header:

```http
Authorization: Bearer <your_api_key>
```

* Keys are property-scoped. The `propertyId` in the request path must match the property linked to the API key, otherwise the API returns `403`.
* Ensure the key has the `metrics` permission enabled.

## API Access by Plan

API access is included on all plans. Generate API keys from the API Access page under **Utilities** in the sidebar.

* **Plus, Business, Scale**: API access included
* **Enterprise**: Full API access with custom endpoints and priority support

## Versioning

All external endpoints live under `/api/external/v1`. Future versions will be published side-by-side (for example, `/api/external/v2`) so you can migrate when ready.

## Common Parameters

| Name       | Type   | Required              | Notes                                                                                                           |
| ---------- | ------ | --------------------- | --------------------------------------------------------------------------------------------------------------- |
| `start`    | string | Yes                   | ISO-8601 timestamp or date (e.g. `2024-05-01` or `2024-05-01T00:00:00Z`).                                       |
| `end`      | string | Yes                   | ISO-8601 timestamp or date that occurs after `start`.                                                           |
| `timezone` | string | No                    | IANA zone name (defaults to `UTC`). Determines bucket boundaries and how timestamps are formatted in responses. |
| `limit`    | number | No                    | Maximum results to return (default: 50).                                                                        |
| `page`     | string | For details endpoints | URL path to filter (e.g. `/pricing`). Required for detail endpoints.                                            |
| `source`   | string | No                    | Filter forms by source.                                                                                         |

Requests that cannot be parsed—invalid dates, unsupported timezones, `end` before `start`, ranges that are too large—return `400` with a descriptive error payload.

***

## Traffic Trends

```
GET /properties/{propertyId}/traffic/trends
```

Returns time-series metrics for page views and unique visitors within a specified range.

### Query Parameters

| Name          | Type | Required | Default | Notes                                            |
| ------------- | ---- | -------- | ------- | ------------------------------------------------ |
| `granularity` | enum | No       | `day`   | Accepted values: `hour`, `day`, `week`, `month`. |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/traffic/trends?start=2024-05-01&end=2024-05-07&granularity=day&timezone=America/New_York"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "start": "2024-05-01T04:00:00.000Z",
    "end": "2024-05-07T03:59:59.000Z",
    "granularity": "day",
    "timezone": "America/New_York",
    "bucket_count": 7
  },
  "data": [
    {
      "bucket_start": "2024-05-01T00:00:00-04:00",
      "bucket_end": "2024-05-01T23:59:59-04:00",
      "page_views": 1523,
      "unique_visitors": 682
    }
  ],
  "summary": {
    "page_views": 9056,
    "unique_visitors": 3142
  }
}
```

### Notes

* Buckets include zero-filled entries when no activity occurred so charting remains continuous.
* Maximum of 500 buckets per request. Very granular windows (for example, hourly over multiple months) return `400`.
* The API excludes known bots automatically to align with the dashboard totals.

***

## Traffic Summary

```
GET /properties/{propertyId}/traffic/summary
```

Returns aggregate traffic metrics for a specified range, including total page views, sessions, bounce rate, and average session duration.

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/traffic/summary?start=2024-05-01&end=2024-05-07&timezone=America/New_York"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "start": "2024-05-01T04:00:00.000Z",
    "end": "2024-05-07T03:59:59.000Z",
    "timezone": "America/New_York"
  },
  "data": {
    "page_views": 9056,
    "sessions": 3142,
    "unique_visitors": 2418,
    "bounce_rate": 0.423,
    "avg_session_duration": 184.5
  }
}
```

### Notes

* `bounce_rate` is expressed as a decimal (e.g. `0.423` = 42.3%).
* `avg_session_duration` is in seconds.
* Bot traffic is excluded automatically.

***

## Traffic Realtime

```
GET /properties/{propertyId}/traffic/realtime
```

Returns the current live visitor count and a feed of recent visitor activity. This endpoint does **not** require `start`, `end`, or `timezone` parameters.

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/traffic/realtime"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID"
  },
  "data": {
    "active_visitors": 23,
    "feed": [
      {
        "page": "/pricing",
        "referrer": "google",
        "device": "desktop",
        "country": "US",
        "timestamp": "2024-05-07T14:32:18.000Z"
      }
    ]
  }
}
```

### Notes

* This endpoint returns a snapshot of current activity — no date range parameters are needed.
* The `feed` array shows the most recent visitor events in reverse chronological order.
* `active_visitors` reflects sessions active within the last few minutes.

***

## Traffic Breakdown

```
GET /properties/{propertyId}/traffic/breakdown
```

Returns the top traffic segments (UTM attributes, countries, devices, landing pages, and referrers) for a specified range.

### Query Parameters

| Name    | Type   | Required | Default | Notes                                                      |
| ------- | ------ | -------- | ------- | ---------------------------------------------------------- |
| `limit` | number | No       | 10      | Maximum entries per segment (maximum supported value: 50). |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/traffic/breakdown?start=2024-05-01T00:00:00Z&end=2024-05-31T23:59:59Z&timezone=UTC&limit=20"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "start": "2024-05-01T00:00:00.000Z",
    "end": "2024-05-31T23:59:59.000Z",
    "timezone": "UTC",
    "limit": 20,
    "totals": {
      "sessions": 1982,
      "page_views": 5478
    }
  },
  "data": {
    "utm": [
      {
        "source": "google",
        "medium": "cpc",
        "campaign": "spring_launch",
        "sessions": 412,
        "page_views": 921,
        "share": 0.208
      }
    ],
    "countries": [
      {
        "country": "US",
        "sessions": 982,
        "page_views": 2015,
        "share": 0.495
      }
    ],
    "devices": [
      {
        "device": "desktop",
        "sessions": 1045,
        "page_views": 2684,
        "share": 0.527
      }
    ],
    "landing_pages": [
      {
        "path": "/pricing",
        "sessions": 213,
        "page_views": 425,
        "share": 0.107
      }
    ],
    "referrers": [
      {
        "referrer": "google",
        "sessions": 643,
        "page_views": 1580,
        "share": 0.324
      }
    ]
  }
}
```

### Notes

* `share` represents the fraction of total sessions contributed by each row.
* Null or missing values are returned as `"unknown"` so you do not need to special-case missing fields.
* Device values are normalized (`desktop`, `mobile`, `unknown`) using Humblytics’ device classification.

***

## Traffic Entry & Exit Pages

```
GET /properties/{propertyId}/traffic/entry-exit-pages
```

Returns the top entry pages (where sessions begin) and exit pages (where sessions end) for a specified range.

### Query Parameters

| Name    | Type   | Required | Default | Notes                                                   |
| ------- | ------ | -------- | ------- | ------------------------------------------------------- |
| `limit` | number | No       | 10      | Maximum entries per list (maximum supported value: 50). |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/traffic/entry-exit-pages?start=2024-05-01&end=2024-05-31&timezone=UTC&limit=10"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "start": "2024-05-01T00:00:00.000Z",
    "end": "2024-05-31T23:59:59.000Z",
    "timezone": "UTC",
    "limit": 10
  },
  "data": {
    "entry_pages": [
      {
        "path": "/",
        "sessions": 982,
        "share": 0.495
      },
      {
        "path": "/pricing",
        "sessions": 312,
        "share": 0.157
      }
    ],
    "exit_pages": [
      {
        "path": "/pricing",
        "sessions": 534,
        "share": 0.269
      },
      {
        "path": "/blog",
        "sessions": 289,
        "share": 0.146
      }
    ]
  }
}
```

### Notes

* `share` represents the fraction of total sessions for each entry or exit page.
* Entry pages indicate where visitors first land; exit pages indicate the last page viewed before leaving.

***

## Pages Breakdown

```
GET /properties/{propertyId}/pages/breakdown
```

Returns performance metrics for all pages, including views, unique visitors, average scroll depth, and bounce rate.

### Query Parameters

| Name    | Type   | Required | Default | Notes                                                    |
| ------- | ------ | -------- | ------- | -------------------------------------------------------- |
| `limit` | number | No       | 10      | Maximum entries to return (maximum supported value: 50). |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/pages/breakdown?start=2024-05-01&end=2024-05-31&timezone=UTC&limit=20"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "start": "2024-05-01T00:00:00.000Z",
    "end": "2024-05-31T23:59:59.000Z",
    "timezone": "UTC",
    "limit": 20
  },
  "data": [
    {
      "path": "/",
      "page_views": 3245,
      "unique_visitors": 2108,
      "avg_scroll_depth": 0.62,
      "bounce_rate": 0.38
    },
    {
      "path": "/pricing",
      "page_views": 1823,
      "unique_visitors": 1456,
      "avg_scroll_depth": 0.74,
      "bounce_rate": 0.29
    }
  ]
}
```

### Notes

* `avg_scroll_depth` is a decimal representing the average percentage of the page scrolled (e.g. `0.62` = 62%).
* `bounce_rate` is page-level, not site-level.
* Results are sorted by `page_views` in descending order by default.

***

## Pages Details

```
GET /properties/{propertyId}/pages/details
```

Returns a deep dive for a single page, including UTM attribution, device breakdown, and country breakdown.

### Query Parameters

| Name    | Type   | Required | Default | Notes                                           |
| ------- | ------ | -------- | ------- | ----------------------------------------------- |
| `page`  | string | Yes      | N/A     | The page path to get details for (URL-encoded). |
| `limit` | number | No       | 10      | Maximum entries per breakdown (maximum: 50).    |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/pages/details?page=%2Fpricing&start=2024-05-01&end=2024-05-31&timezone=UTC"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "page": "/pricing",
    "start": "2024-05-01T00:00:00.000Z",
    "end": "2024-05-31T23:59:59.000Z",
    "timezone": "UTC"
  },
  "data": {
    "page_views": 1823,
    "unique_visitors": 1456,
    "avg_scroll_depth": 0.74,
    "bounce_rate": 0.29,
    "utm": [
      {
        "source": "google",
        "medium": "cpc",
        "campaign": "spring_launch",
        "page_views": 412,
        "share": 0.226
      }
    ],
    "devices": [
      {
        "device": "desktop",
        "page_views": 1102,
        "share": 0.604
      }
    ],
    "countries": [
      {
        "country": "US",
        "page_views": 845,
        "share": 0.463
      }
    ]
  }
}
```

### Notes

* Use URL encoding for the `page` parameter (e.g. `/pricing page` becomes `%2Fpricing%20page`).
* Breakdowns (UTM, devices, countries) are specific to the requested page.
* Combines aggregate page metrics with dimensional breakdowns in a single response.

***

## Clicks Breakdown

```
GET /properties/{propertyId}/clicks/breakdown
```

Returns aggregated click event data grouped by page and click target, along with trend data over time.

### Query Parameters

| Name          | Type   | Required | Default | Notes                                                      |
| ------------- | ------ | -------- | ------- | ---------------------------------------------------------- |
| `granularity` | enum   | No       | `day`   | Accepted values: `hour`, `day`, `week`, `month`.           |
| `limit`       | number | No       | 10      | Maximum entries per segment (maximum supported value: 50). |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/clicks/breakdown?start=2024-05-01&end=2024-05-07&granularity=day&timezone=UTC&limit=20"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "start": "2024-05-01T00:00:00.000Z",
    "end": "2024-05-07T23:59:59.000Z",
    "timezone": "UTC",
    "granularity": "day",
    "limit": 20,
    "bucket_count": 7
  },
  "data": [
    {
      "page": "/pricing",
      "target": "Get Started Button",
      "clicks": 342,
      "unique_clicks": 289
    },
    {
      "page": "/home",
      "target": "Sign Up Link",
      "clicks": 128,
      "unique_clicks": 115
    }
  ],
  "trend": [
    {
      "bucket_start": "2024-05-01T00:00:00.000Z",
      "bucket_end": "2024-05-01T23:59:59.000Z",
      "clicks": 412,
      "unique_clicks": 352
    }
  ],
  "summary": {
    "total_clicks": 2849,
    "total_unique_clicks": 2341
  }
}
```

### Notes

* Returns both page-level click aggregations and time-series trend data in a single response.
* Click targets are automatically extracted from tracked click events.
* `unique_clicks` counts distinct sessions that performed the click action.

***

## Clicks Details

```
GET /properties/{propertyId}/clicks/details
```

Returns detailed click event breakdown for a specific page, showing which elements were clicked.

### Query Parameters

| Name          | Type   | Required | Default | Notes                                                |
| ------------- | ------ | -------- | ------- | ---------------------------------------------------- |
| `page`        | string | Yes      | N/A     | The page path to get click details for (URL-encoded) |
| `granularity` | enum   | No       | `day`   | Accepted values: `hour`, `day`, `week`, `month`.     |
| `limit`       | number | No       | 10      | Maximum entries to return (maximum: 50).             |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/clicks/details?page=%2Fpricing&start=2024-05-01&end=2024-05-07&granularity=day&timezone=UTC&limit=20"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "page": "/pricing",
    "start": "2024-05-01T00:00:00.000Z",
    "end": "2024-05-07T23:59:59.000Z",
    "timezone": "UTC",
    "granularity": "day",
    "limit": 20,
    "bucket_count": 7
  },
  "data": {
    "clicks": [
      {
        "target": "Get Started Button",
        "clicks": 342,
        "unique_clicks": 289,
        "share": 0.473
      },
      {
        "target": "Learn More Link",
        "clicks": 128,
        "unique_clicks": 115,
        "share": 0.177
      }
    ]
  },
  "summary": {
    "total_clicks": 723,
    "total_unique_clicks": 615
  }
}
```

### Notes

* Use URL encoding for the `page` parameter (e.g., `/pricing page` becomes `%2Fpricing%20page`).
* `share` represents the proportion of total clicks on that page attributed to each target.
* Returns only clicks that occurred on the specified page.

***

## Forms Breakdown

```
GET /properties/{propertyId}/forms/breakdown
```

Returns aggregated form submission data grouped by page and form target, along with trend data over time.

### Query Parameters

| Name          | Type   | Required | Default | Notes                                                      |
| ------------- | ------ | -------- | ------- | ---------------------------------------------------------- |
| `granularity` | enum   | No       | `day`   | Accepted values: `hour`, `day`, `week`, `month`.           |
| `limit`       | number | No       | 10      | Maximum entries per segment (maximum supported value: 50). |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/forms/breakdown?start=2024-05-01&end=2024-05-07&granularity=day&timezone=UTC&limit=20"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "start": "2024-05-01T00:00:00.000Z",
    "end": "2024-05-07T23:59:59.000Z",
    "timezone": "UTC",
    "granularity": "day",
    "limit": 20,
    "bucket_count": 7
  },
  "data": [
    {
      "page": "/contact",
      "target": "Contact Form",
      "submissions": 89,
      "unique_submissions": 82
    },
    {
      "page": "/signup",
      "target": "Registration Form",
      "submissions": 156,
      "unique_submissions": 147
    }
  ],
  "trend": [
    {
      "bucket_start": "2024-05-01T00:00:00.000Z",
      "bucket_end": "2024-05-01T23:59:59.000Z",
      "submissions": 34,
      "unique_submissions": 31
    }
  ],
  "summary": {
    "total_submissions": 245,
    "total_unique_submissions": 229
  }
}
```

### Notes

* Returns both page-level submission aggregations and time-series trend data in a single response.
* Form targets are automatically extracted from tracked form submission events.
* `unique_submissions` counts distinct sessions that submitted a form.

***

## Forms Details

```
GET /properties/{propertyId}/forms/details
```

Returns detailed form submission breakdown for a specific page, showing which forms were submitted.

### Query Parameters

| Name          | Type   | Required | Default | Notes                                               |
| ------------- | ------ | -------- | ------- | --------------------------------------------------- |
| `page`        | string | Yes      | N/A     | The page path to get form details for (URL-encoded) |
| `granularity` | enum   | No       | `day`   | Accepted values: `hour`, `day`, `week`, `month`.    |
| `limit`       | number | No       | 10      | Maximum entries to return (maximum: 50).            |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/forms/details?page=%2Fcontact&start=2024-05-01&end=2024-05-07&granularity=day&timezone=UTC&limit=20"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "page": "/contact",
    "start": "2024-05-01T00:00:00.000Z",
    "end": "2024-05-07T23:59:59.000Z",
    "timezone": "UTC",
    "granularity": "day",
    "limit": 20,
    "bucket_count": 7
  },
  "data": {
    "forms": [
      {
        "target": "Contact Form",
        "submissions": 89,
        "unique_submissions": 82,
        "share": 0.687
      },
      {
        "target": "Newsletter Signup",
        "submissions": 41,
        "unique_submissions": 39,
        "share": 0.313
      }
    ]
  },
  "summary": {
    "total_submissions": 130,
    "total_unique_submissions": 121
  }
}
```

### Notes

* Use URL encoding for the `page` parameter (e.g., `/contact us` becomes `%2Fcontact%20us`).
* `share` represents the proportion of total form submissions on that page attributed to each form.
* Returns only form submissions that occurred on the specified page.

***

## Funnels

```
GET /properties/{propertyId}/funnels
```

Runs a funnel query across a defined sequence of steps, returning conversion rates between each step.

### Query Parameters

| Name          | Type   | Required | Default     | Notes                                                                                 |
| ------------- | ------ | -------- | ----------- | ------------------------------------------------------------------------------------- |
| `steps`       | JSON   | Yes      | N/A         | JSON array of funnel step definitions (URL-encoded).                                  |
| `mode`        | enum   | No       | `unbounded` | `unbounded` (steps in any order) or `sequential` (steps must occur in defined order). |
| `breakdownBy` | string | No       | N/A         | Optional dimension to break results down by (e.g. `device`, `country`, `utm_source`). |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/funnels?start=2024-05-01&end=2024-05-31&timezone=UTC&steps=%5B%7B%22page%22%3A%22%2F%22%7D%2C%7B%22page%22%3A%22%2Fpricing%22%7D%2C%7B%22page%22%3A%22%2Fsignup%22%7D%5D&mode=sequential"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "start": "2024-05-01T00:00:00.000Z",
    "end": "2024-05-31T23:59:59.000Z",
    "timezone": "UTC",
    "mode": "sequential"
  },
  "data": {
    "steps": [
      {
        "step": 1,
        "page": "/",
        "sessions": 3142,
        "conversion_rate": 1.0
      },
      {
        "step": 2,
        "page": "/pricing",
        "sessions": 1256,
        "conversion_rate": 0.4
      },
      {
        "step": 3,
        "page": "/signup",
        "sessions": 314,
        "conversion_rate": 0.25
      }
    ],
    "overall_conversion_rate": 0.1
  }
}
```

### Notes

* The `steps` parameter must be a JSON-encoded array. URL-encode it when passing as a query parameter.
* `conversion_rate` at each step is relative to the previous step. `overall_conversion_rate` is step 1 → last step.
* Use `mode=sequential` when order matters (e.g. homepage → pricing → signup). Use `unbounded` for unordered funnels.

***

## Funnels Sankey

```
GET /properties/{propertyId}/funnels/sankey
```

Returns path flow data for a funnel in a Sankey diagram format, showing how sessions move between steps.

### Query Parameters

Accepts all the same parameters as the `/funnels` endpoint, plus:

| Name          | Type   | Required | Default | Notes                                        |
| ------------- | ------ | -------- | ------- | -------------------------------------------- |
| `maxPaths`    | number | No       | 20      | Maximum number of paths to return.           |
| `minSessions` | number | No       | 1       | Minimum sessions a path must have to appear. |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/funnels/sankey?start=2024-05-01&end=2024-05-31&timezone=UTC&steps=%5B%7B%22page%22%3A%22%2F%22%7D%2C%7B%22page%22%3A%22%2Fpricing%22%7D%2C%7B%22page%22%3A%22%2Fsignup%22%7D%5D&mode=sequential&maxPaths=10&minSessions=5"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "start": "2024-05-01T00:00:00.000Z",
    "end": "2024-05-31T23:59:59.000Z",
    "timezone": "UTC",
    "mode": "sequential",
    "maxPaths": 10,
    "minSessions": 5
  },
  "data": {
    "paths": [
      {
        "nodes": ["/", "/pricing", "/signup"],
        "sessions": 245
      },
      {
        "nodes": ["/", "/pricing", "(drop-off)"],
        "sessions": 892
      },
      {
        "nodes": ["/", "(drop-off)"],
        "sessions": 1024
      }
    ]
  }
}
```

### Notes

* `(drop-off)` nodes indicate where sessions exited the funnel.
* Use `maxPaths` and `minSessions` to control the granularity of the output.
* Useful for visualizing where users leave the funnel and which alternative paths they take.

***

## Funnels Suggestions

```
GET /properties/{propertyId}/funnels/suggestions
```

Returns AI-generated funnel suggestions for a specific page, based on traffic patterns and user behavior.

### Query Parameters

| Name   | Type   | Required | Default | Notes                                        |
| ------ | ------ | -------- | ------- | -------------------------------------------- |
| `page` | string | Yes      | N/A     | The page path to get funnel suggestions for. |

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/funnels/suggestions?page=/pricing"
```

### Sample Response

```json
{
  "meta": {
    "property_id": "PROPERTY_ID",
    "page": "/pricing"
  },
  "data": [
    {
      "name": "Pricing to Signup Flow",
      "steps": [
        { "page": "/pricing" },
        { "page": "/signup" },
        { "page": "/welcome" }
      ],
      "rationale": "62% of signups visit the pricing page first. This funnel tracks the primary conversion path."
    }
  ]
}
```

### Notes

* Suggestions are based on your actual traffic data, not generic templates.
* Each suggestion includes a human-readable `rationale` explaining why the funnel is recommended.
* Use these suggestions as a starting point — you can modify the steps before saving.

***

## Saved Funnels

### List Saved Funnels

```
GET /properties/{propertyId}/saved-funnels
```

Returns all saved funnel configurations for the property.

### Sample Request

```bash
curl \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/saved-funnels"
```

### Sample Response

```json
{
  "data": [
    {
      "id": "funnel_abc123",
      "name": "Homepage to Signup",
      "steps": [
        { "page": "/" },
        { "page": "/pricing" },
        { "page": "/signup" }
      ],
      "created_at": "2024-05-01T10:00:00.000Z"
    }
  ]
}
```

### Create or Update a Saved Funnel

```
POST /properties/{propertyId}/saved-funnels
```

Creates a new saved funnel configuration. Include `id` in the body to update an existing funnel.

### Request Body

| Field   | Type   | Required | Notes                                            |
| ------- | ------ | -------- | ------------------------------------------------ |
| `id`    | string | No       | Include to update an existing saved funnel.      |
| `name`  | string | Yes      | A descriptive name for the funnel.               |
| `steps` | array  | Yes      | Array of step objects, each with a `page` field. |

### Sample Request

```bash
curl -X POST \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Homepage to Signup",
    "steps": [
      { "page": "/" },
      { "page": "/pricing" },
      { "page": "/signup" }
    ]
  }' \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/saved-funnels"
```

### Sample Response (201 Created)

```json
{
  "id": "funnel_abc123",
  "name": "Homepage to Signup",
  "steps": [
    { "page": "/" },
    { "page": "/pricing" },
    { "page": "/signup" }
  ],
  "created_at": "2024-05-01T10:00:00.000Z"
}
```

### Delete a Saved Funnel

```
DELETE /properties/{propertyId}/saved-funnels/{funnelId}
```

Deletes a saved funnel configuration.

### Sample Request

```bash
curl -X DELETE \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  "https://app.humblytics.com/api/external/v1/properties/PROPERTY_ID/saved-funnels/funnel_abc123"
```

### Notes

* Deleting a saved funnel does not affect historical funnel query results.
* Saved funnels are property-scoped — they are visible to all API keys for the same property.

***

## Multi-Property Aggregate

These `POST` endpoints let you query data across multiple properties in a single request. Send a JSON body with `{ "propertyIds": [...] }` along with the same query parameters used by the corresponding single-property endpoints.

All aggregate endpoints require the API key to have access to every property listed in the request.

| Endpoint                                              | Description                                        |
| ----------------------------------------------------- | -------------------------------------------------- |
| `POST /properties/aggregate/traffic/trends`           | Aggregate traffic trends across properties.        |
| `POST /properties/aggregate/traffic/summary`          | Aggregate traffic summary across properties.       |
| `POST /properties/aggregate/traffic/breakdown`        | Aggregate traffic breakdowns across properties.    |
| `POST /properties/aggregate/traffic/realtime`         | Aggregate realtime visitor data across properties. |
| `POST /properties/aggregate/traffic/entry-exit-pages` | Aggregate entry/exit pages across properties.      |
| `POST /properties/aggregate/clicks/breakdown`         | Aggregate click data across properties.            |
| `POST /properties/aggregate/forms/breakdown`          | Aggregate form submission data across properties.  |

### Sample Request

```bash
curl -X POST \
  -H "Authorization: Bearer $HUMBLYTICS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "propertyIds": ["prop_abc123", "prop_def456"]
  }' \
  "https://app.humblytics.com/api/external/v1/properties/aggregate/traffic/summary?start=2024-05-01&end=2024-05-31&timezone=UTC"
```

### Notes

* Response format matches the corresponding single-property endpoint, with data aggregated across all specified properties.
* The `meta` object will include a `property_ids` array instead of a single `property_id`.
* The realtime aggregate endpoint does not require date parameters, same as the single-property version.

***

## Errors

| Status | Code              | When it happens                                                                       |
| ------ | ----------------- | ------------------------------------------------------------------------------------- |
| `400`  | `invalid_request` | Bad dates, unsupported timezone or granularity, ranges that are too large.            |
| `401`  | `unauthorized`    | Missing or invalid API key header.                                                    |
| `403`  | `forbidden`       | Property ID does not match the API key or the key does not have `metrics` permission. |
| `429`  | `rate_limited`    | Too many requests in a short window (limits will evolve with usage).                  |
| `500`  | `internal_error`  | Unexpected server error. Retry later or contact support.                              |

Error payloads follow this structure:

```json
{
  "error": {
    "code": "invalid_request",
    "message": "Unsupported granularity: minute",
    "details": {
      "field": "granularity"
    }
  }
}
```

***

## Best Practices

* Store API keys securely (environment variables or a secret manager) and rotate them periodically.
* Use the `timezone` parameter to align data with the local reporting context you care about.
* Cache responses when possible—trend and breakdown data only changes when new traffic arrives.
* Start with coarser granularity (e.g. `day`) for large ranges, then request narrower windows for detailed analysis.
* Use the **Multi-Property Aggregate** endpoints to consolidate reporting across multiple sites without making separate requests per property.
* Save frequently-used funnel definitions with the **Saved Funnels** endpoints so they can be re-run without redefining steps each time.
* **Looking for A/B testing endpoints?** See the [Split Testing API](/split-testing-api.md) to get AI-powered test recommendations, create no-code experiments, and manage running tests programmatically.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.humblytics.com/external-analytics-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
