---
title: "Get sitewide timeseries"
method: POST
path: "/v25-10-beta/analytics/sitewide/timeseries"
tags: ["Fetch Sitewide Analytics"]
---

# Get sitewide timeseries

`POST /v25-10-beta/analytics/sitewide/timeseries`

## Request

- Base URL: `https://api.intelligems.io`
- URL: `https://api.intelligems.io/v25-10-beta/analytics/sitewide/timeseries`
- Auth: API key in header `intelligems-access-token`
- TypeScript: <https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta/docs/v25-10-beta/analytics/sitewide/timeseries/post.ts> (a function with typed inputs; its response is checked against the schema)

Returns sitewide KPI time-series data with configurable granularity, a choice of metric set, and optional audience segmentation.

### Parameters

- `start` — optional **ISO 8601 datetime string**. Beginning of the analysis window. Defaults to the start of the week (Monday, store timezone) containing the date 12 weeks ago.
- `end` — optional **ISO 8601 datetime string**. End of the analysis window. Defaults to now (rounded to the cache interval).
- `granularity` — optional time bucketing: `day`, `week` (default), or `month`
- `feature` — optional metric-set selector object. **These sets belong to this endpoint.** They are not the same as the sets on `POST /analytics/sitewide/snapshot` — the two endpoints compute different metrics, so a set with the same name returns different fields on each. See "Metric sets" below.

> **The window is `start` / `end`, not `startTs` / `endTs`.** Every `/analytics/sitewide/*` endpoint takes ISO 8601 datetime strings under `start` and `end`. The epoch-seconds `startTs` / `endTs` pair used by the experience endpoints (`/analytics/resource/{experienceId}`, `/analytics/experience/{experienceId}/timeseries`, `/analytics/experience/{experienceId}/export`) is **not** accepted here: unknown fields are stripped rather than rejected, so a request sending `startTs` / `endTs` returns `200` over this endpoint's **default window** — from the start of the week (Monday, store timezone) 12 weeks ago until now — instead of the range you asked for, and nothing in the response flags the substitution. The default differs per sitewide endpoint, so always pass an explicit `start` when you need a specific window. Date-only strings and datetimes without an offset are rejected — send a full datetime with `Z` or an offset (`"2026-06-01T00:00:00Z"`, not `"2026-06-01"` or `"2026-06-01T00:00:00"`).

### Response envelope

Segments are nested under a top-level `segments` key, alongside `currency` and the resolved `granularity`. This differs from `POST /analytics/sitewide/snapshot`, where segment names are themselves the top-level keys:

```json
{
  "currency": "USD",
  "granularity": "week",
  "segments": {
    "All": {
      "data": [{ "dt": "2026-06-01T00:00:00", "n_orders": 142 }],
      "summary": { "n_orders": 181.75 }
    }
  }
}
```

### Metric sets

Omit `feature` to receive every metric this endpoint produces. Pass one of the following to receive only that set:

| `feature`                                           | Segment keys        | Fields returned (in addition to `dt`)                                                                                                                                                                                                                                                                                                                                           |
| --------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ "name": "performance" }`                         | `"All"`             | `n_visitors`, `n_orders`, `conversion_rate`, `aov`, `net_revenue`, `net_revenue_per_visitor`, `gross_profit`, `gross_profit_per_visitor`, `gross_margin_pct`, `pct_revenue_with_cogs`                                                                                                                                                                                           |
| `{ "name": "order" }`                               | `"All"`             | `n_orders`, `aov`, `aov_pre_discount`, `units_per_order`, `net_revenue_per_unit`, `gross_revenue_per_unit`, `discount_per_unit`, `pct_orders_with_free_shipping`, `net_shipping_revenue_per_order`                                                                                                                                                                              |
| `{ "name": "conversion" }`                          | `"All"`             | Funnel step rates — `viewed_collection_page_rate`, `viewed_product_page_rate`, `add_to_cart_rate`, `checkout_begin_rate`, `conversion_rate`, `bounce_rate`, `abandoned_cart_rate`, `abandoned_checkout_rate` — plus the four counts those rates are derived from: `n_sessions`, `n_visitors`, `n_visitors_abandoned_cart`, `n_visitors_abandoned_checkout` (12 fields in total) |
| `{ "name": "audience", "audience": "device_type" }` | one key per segment | The full per-segment metric set for the chosen dimension                                                                                                                                                                                                                                                                                                                        |

The endpoint produces 37 metrics in total; `performance` and `order` between them cover 17. The remaining 20 are returned **only** when `feature` is omitted:

`n_sessions`, `sessions_per_visitor`, `conversion_rate_per_session`, `net_revenue_per_session`, `gross_profit_per_session`, `gross_revenue`, `net_product_revenue`, `net_shipping_revenue`, `order_cogs`, `oli_net_product_revenue`, `oli_net_product_revenue_with_cogs`, `unit_quantity`, `lost_orders`, `lost_net_revenue`, `n_free_shipping_orders`, `discounts`, `shipping_cost`, `transaction_fees`, `tax`, `cost_of_revenue`

Several of those — the per-session rates and `cost_of_revenue` — cannot be produced by the snapshot endpoint at all. Conversely, `median_order_value` and `average_discount` are available only on the snapshot endpoint and are never returned here.

`conversion` and `audience` are served by dedicated datasets, so their field sets are fixed by those datasets rather than filtered from the general metric set.

### `dt` Field Format

`dt` is returned as a formatted date string (not Unix epoch). Format is `"YYYY-MM-DDTHH:mm:ss"` for all granularities (`day`, `week`, and `month`).

### Response Notes

- Each data point contains `dt` plus the numeric fields for the selected metric set.
- Fields are `null` rather than `0` when a bucket has no data to compute them from (for example `conversion_rate` in a bucket with no visitors).
- **`summary` and `data` do not share a key set, and how far they diverge depends on the metric set.** Compare keys rather than assuming a fixed relationship:
  - no `feature` — `data` has 37 fields, `summary` has 36. `sessions_per_visitor` appears on each data point but is not summarized.
  - `performance`, `order` — identical key sets (10 and 9 fields respectively).
  - `conversion` — `data` has 12 fields but `summary` carries only `n_sessions` and `n_visitors`. The eight funnel rates and the two abandonment counts are **not** summarized; recompute a window-level rate from the counts, or read it from `POST /analytics/sitewide/snapshot`.
  - `audience` — one segment per dimension value, each with its own `data` / `summary`. There is no `__total` segment here (unlike `POST /analytics/sitewide/snapshot`), and data points additionally carry `audience` plus the within-bucket shares `pct_visitors_by_audience`, `pct_orders_by_audience`, `pct_net_revenue_by_audience`, and `pct_gross_profit_by_audience`.
- **Profit metrics are nulled when the store has no COGS coverage.** `pct_revenue_with_cogs` is returned alongside the profit metrics on both `data` points and `summary`; when it is `0`, `gross_profit`, `gross_profit_per_visitor`, `gross_margin_pct`, and `oli_net_product_revenue_with_cogs` come back as `null` rather than as revenue-minus-zero-cost figures. Suppression is evaluated per bucket and independently for `summary`, so a window can mix suppressed and unsuppressed buckets. Partial coverage (`0 < pct_revenue_with_cogs < 1`) keeps the values — they are blended, and the coverage figure is how you tell.

### `summary` is not a window total

Each segment can include a `summary` object alongside `data`, but **it is not the sum over the requested window**, and the two kinds of metric behave differently:

- **Additive metrics** — `n_sessions`, `n_orders`, `gross_revenue`, `net_product_revenue`, `net_shipping_revenue`, `n_free_shipping_orders`, `net_revenue`, `order_cogs`, `oli_net_product_revenue_with_cogs`, `oli_net_product_revenue`, `unit_quantity`, `lost_orders`, `lost_net_revenue`, `discounts`, `shipping_cost`, `transaction_fees`, `tax`, `cost_of_revenue`, `gross_profit` — are the window sum **rescaled to one `granularity` bucket**, i.e. an average per bucket. The same window therefore returns different values at `day`, `week`, and `month`, and counts come back **fractional**. Summing the `data` array recovers the true window total for these.
- **Ratio metrics** — `conversion_rate`, `conversion_rate_per_session`, `aov`, `aov_pre_discount`, `net_revenue_per_visitor`, `net_revenue_per_session`, `gross_profit_per_visitor`, `gross_profit_per_session`, `units_per_order`, `gross_revenue_per_unit`, `net_revenue_per_unit`, `discount_per_unit`, `gross_margin_pct`, `pct_orders_with_free_shipping`, `net_shipping_revenue_per_order`, `pct_revenue_with_cogs` — are computed from the window sums rather than from the rescaled per-bucket values. Ratios whose denominator is not visitor-based (`aov`, `gross_margin_pct`, `pct_revenue_with_cogs`, …) are exact window-wide figures and do not vary with `granularity`. **Visitor-denominated ratios currently do vary — see the warning below.**
- **`n_visitors` is not additive.** It is a distinct-visitor count, so a visitor active on several days is counted once per bucket they appear in. Summing `data[].n_visitors` **overcounts**, and the overcount grows as buckets get smaller. `summary.n_visitors` is rescaled like the additive metrics, so it is not a window total either. For a true unique-visitor count over a window, use `POST /analytics/sitewide/snapshot`.

**To get a window total for an additive metric, sum the `data` array yourself. This does not work for `n_visitors`.**

Example — one request window whose true totals are `727` orders and `138,938` unique visitors, requested as `start` `2026-06-01T00:00:00.000Z` / `end` `2026-06-29T00:00:00.000Z`. The window is closed and historical, so these figures reproduce exactly on re-run. **They are sensitive to the `end` time of day, though:** as with the bucket rounding on the other endpoints, an `end` of `2026-06-29T23:59:59Z` rolls into one more day bucket and the same window returns `756` orders and `165,397` summed visitors instead. Align `end` to a day boundary to reproduce the table. The relationships it teaches — `sum(data[])` constant across granularities, `summary` scaling by `bucket_days / window_days`, visitor sums shrinking toward the true count as buckets widen — hold either way:

| `granularity` | `summary.n_orders` | `sum(data[].n_orders)` | `sum(data[].n_visitors)` | `summary.conversion_rate` |
| ------------- | ------------------ | ---------------------- | ------------------------ | ------------------------- |
| `day`         | `25.96`            | `727`                  | `158,528` (+14.1%)       | `0.0045859`               |
| `week`        | `181.75`           | `727`                  | `146,665` (+5.6%)        | `0.0049569`               |
| `month`       | `791.91`           | `727`                  | `138,938` (exact)        | `0.0052325`               |

The additive scale factor is `bucket_days / window_days` (`1`, `7`, and `30.5` respectively), which is why `month` on a 28-day window exceeds the true total.

> **Known issue — visitor-denominated summary ratios vary with `granularity`.** `summary.conversion_rate`, `summary.net_revenue_per_visitor`, and `summary.gross_profit_per_visitor` are computed as `numerator / sum(data[].n_visitors)`. Because that denominator double-counts returning visitors, these three are understated at `day` and `week` granularity and only correct when the window fits in a single bucket. In the example above the true conversion rate is `0.0052325` (confirmed against `/analytics/sitewide/snapshot` for the same window), but `day` reports `0.0045859` — a 12.3% understatement. Until this is fixed, read these three from `POST /analytics/sitewide/snapshot`, or compute them yourself from `sum(data[].n_orders)` and the snapshot's `n_visitors`. Ratios with non-visitor denominators are unaffected.

**Rate Limit:** 10 requests per 30s window, refilling 5 tokens every 30s.

## Request body

- object
  - `start` string, date-time: Start of analysis period as an ISO 8601 datetime string (e.g. '2025-01-01T00:00:00.000-05:00'). Defaults to the start of the week containing the date 12 weeks ago, in the store's timezone (weeks start Monday), so the default start is week-aligned rather than exactly 84 days back. Note the default differs per sitewide endpoint, so pass an explicit start if you need a specific window.
  - `end` string, date-time: End of analysis period as an ISO 8601 datetime string. Defaults to now.
  - `feature` union: Optional metric-set selector. Object form, e.g. { "name": "performance" }. Values: 'performance' (headline KPI trend), 'order' (order composition and per-unit economics), 'conversion' (funnel step rates), or { name: 'audience', audience: '<dimension>' } for a per-segment breakdown. Omit to receive every metric this endpoint produces. NOTE: the fields behind each set are specific to this endpoint and differ from the sitewide snapshot endpoint's set of the same name, because the two run different underlying datasets.
    - object
      - `name` 'performance', required
    - object
      - `name` 'audience', required
      - `audience` 'device_type' | 'visitor_type' | 'source_channel' | 'source_site' | 'country_code' | 'landing_page_full_path', required: Optional audience breakdown dimension. When provided, returns per-segment snapshot instead of site-level KPIs. Supported values: device_type, visitor_type, source_channel, source_site, country_code, landing_page_full_path.
    - object
      - `name` 'order', required
    - object
      - `name` 'conversion', required
  - `granularity` 'day' | 'week' | 'month': Time bucket granularity. Supported values: day, week, month. Defaults to week.
  - `filters` object: Optional analytics filters object. See the Filters Reference for available filter fields.
    - `deviceType` 'any' | 'mobile' | 'desktop', nullable: Filter by device type. Options: 'any' (disables filter), 'mobile', 'desktop'. Omit or null to include all devices.
    - `visitorType` 'any' | 'new' | 'returning', nullable: Filter by visitor type. Options: 'any' (disables filter), 'new', 'returning'. Omit or null to include all visitors.
    - `customerType` 'new' | 'returning', nullable: Filter by customer type. Options: 'new', 'returning'. Omit or null to include all customers.
    - `sourceSitesOrChannels` string[]: Filter by traffic source channels. These 25 values are the complete accepted set — the channels the analytics service buckets sessions and orders into — and any other value is rejected with a 400: 'Instagram', 'Facebook', 'Google', 'Twitter', 'TikTok', 'Youtube', 'Klaviyo', 'Attentive', 'Postscript', 'Paid Shopping', 'Paid Search', 'Paid Social', 'Paid Video', 'Display', 'Paid Other', 'Organic Shopping', 'Organic Social', 'Organic Video', 'Organic Search', 'Other', 'Referral', 'Affiliate', 'SMS', 'Email', 'Direct'. Omit or pass an empty array for all channels — there is no 'any' sentinel.
    - `landingPage` object, nullable: DEPRECATED — use landingPageFilters instead, which supports multiple values and an and/or operator. This single-path filter is retained for backwards compatibility and still works, but new integrations should use landingPageFilters. Filter by landing page URL path. Object with: landingPageUrlPath (string|null — the path to match), landingPageUrlPathFilterType (match operator|null: 'equals', 'contains', 'startsWith', 'endsWith', 'doesNotEqual', 'doesNotContain', 'doesNotStartWith', 'doesNotEndWith', 'isNull', 'isNotNull'). REQUIRED COMBINATIONS (enforced with a 400): every operator except 'isNull'/'isNotNull' requires a non-empty landingPageUrlPath; 'isNull'/'isNotNull' take no path, so leave landingPageUrlPath null; and a landingPageUrlPath with no landingPageUrlPathFilterType is rejected. Omit both fields to apply no landing-page filter.
      - `landingPageUrlPath` string, nullable, required
      - `landingPageUrlPathFilterType` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull', nullable, required
    - `landingPageFilters` object[]: Filter by landing page URL path with multi-value support. Recommended landing page filter (supersedes the deprecated landingPage field). Array of filter items, each with: filterType (match operator: 'equals', 'contains', 'startsWith', 'endsWith', 'doesNotEqual', 'doesNotContain', 'doesNotStartWith', 'doesNotEndWith', 'isNull', 'isNotNull') and values (array of strings to match against). REQUIRED COMBINATIONS (enforced with a 400): every operator except 'isNull'/'isNotNull' requires at least one non-empty entry in values — an omitted, empty, or blank-only values array is rejected rather than silently matching nothing. 'isNull'/'isNotNull' take no values; omit the field (an empty array is tolerated, real values are rejected). Multiple values within a single item are OR'd. How items in the array are combined is controlled by landingPageFiltersOperator.
      - `values` string[]
      - `filterType` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull', required
    - `landingPageFiltersOperator` 'or' | 'and': How multiple items in landingPageFilters are combined. 'or' (default) — session matches if any filter item matches. 'and' — session must match every filter item.
    - `countryCodes` string[]: Filter by ISO 3166-1 alpha-2 country codes (e.g. ['US', 'GB', 'CA']). Omit or pass empty array for all countries.
    - `countryCodesFilterType` 'include' | 'exclude': How countryCodes should be matched: 'include' (only visitors in the listed countries) or 'exclude' (visitors in any country except the listed ones). Defaults to 'include' when omitted. Requires countryCodes to be a non-empty array.
    - `currencyCodes` string[]: Filter by ISO 4217 order currency codes (e.g. ['USD', 'GBP', 'CAD']). Matches the currency an order was placed in. Omit or pass empty array for all currencies.
    - `currencyCodesFilterType` 'include' | 'exclude': How currencyCodes should be matched: 'include' (only orders in the listed currencies) or 'exclude' (orders in any currency except the listed ones). Defaults to 'include' when omitted. Requires currencyCodes to be a non-empty array.
    - `maxZScore` union: Maximum Z-score threshold for outlier filtering on order revenue. Visitors with orders whose Z-score exceeds this value are excluded. Accepts number or numeric string. Null or omit to disable outlier filtering.
      - number
      - string
    - `onlyProductIds` string[]: Filter to orders containing at least one of these Shopify product IDs (numeric strings, e.g. ['1234567890', '9876543210']). Omit or pass an empty array for all products.
    - `landingPageTypes` string[]: Filter sessions by landing page types. An array of values from: 'PDP', 'Collection', 'Content', 'Blog', 'Homepage', 'Search', 'Cart', 'Other'. Omit or null to include all landing page types.
    - `allOrders` boolean: Whether to include all orders or only matched orders.

## Response `200`

OK

- object
  - `currency` string, required: ISO 4217 currency code for monetary values (e.g. 'USD').
  - `granularity` 'day' | 'week' | 'month', required: The granularity used for time bucketing.
  - `segments` object, required: Time series data keyed by segment name. Contains 'All' for every feature except `audience`, which returns per-segment keys. Each segment has a `data` array and an optional `summary`. NOTE: `summary` is not a window total — additive metrics in it are rescaled to a single `granularity` bucket (so counts are fractional and change with granularity), while ratio metrics are computed from the unscaled window sums. Sum the `data` array to get a true window total — except for `n_visitors`, which is a distinct count and cannot be summed across buckets. Visitor-denominated ratios (`conversion_rate`, `net_revenue_per_visitor`, `gross_profit_per_visitor`) use a whole-window distinct-visitor aggregation returned alongside the buckets in the same query, so returning visitors are counted once and these ratios do not vary with granularity. The rescaled `summary.n_visitors` remains an average of bucket-level distinct counts; it is not the distinct-visitor count used for those ratios. During a rolling deployment, older pipes that do not return window aggregates cause a warning and retain the legacy bucket-derived visitor ratios.

## Other responses

- `429`: Too Many Requests

## Changes

- **2026-11-06** `7b769b2f90b1`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta/changes/v25-10-beta/analytics/sitewide/timeseries/post.md)

---

[API](https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta.md) - [All operations](https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta/llms.txt) - [OpenAPI document](https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta/revisions/ca5d7c5b1bb6?raw)
