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

# Get sitewide order distribution

`POST /v25-10-beta/analytics/sitewide/order-distribution`

## Request

- Base URL: `https://api.intelligems.io`
- URL: `https://api.intelligems.io/v25-10-beta/analytics/sitewide/order-distribution`
- 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/order-distribution/post.ts> (a function with typed inputs; its response is checked against the schema)

Retrieve order value distribution data and unit mix breakdowns for a time window.

### 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).
- `filters` — optional shared sitewide filters object. See the Filters Reference.

> **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

The response returns `orderValueDistribution.kernel_density_estimate` and `orderValueDistribution.cumulative_distribution_function`, plus `orderBreakdown` and `currency`.

Both distribution arrays hold one entry per sampled order-value point, each with `x` (the order value) and the two series `current_period` and `previous_period`. The two arrays share the same `x` grid, so they can be zipped by index.

`orderBreakdown` is an **array** of unit-mix rows. Each row carries `dt` (the start of its weekly bucket, in the store's timezone, formatted `"YYYY-MM-DD HH:MM:SS"`), a plain-number `unit_quantity`, plus `n_orders`, `net_revenue`, `gross_profit`, and the share metrics `pct_orders_by_unit_quantity`, `pct_revenue_by_unit_quantity`, and `pct_profit_by_unit_quantity`. Each metric is a `{ value }` object.

> **Rows are per week, not per unit quantity.** The unit mix is computed per weekly bucket, so the array holds one row per (`dt` × `unit_quantity`), and the share metrics are shares _within that week_. The buckets cover both the requested window and the equally long comparison window immediately before it. Rows whose `dt` is before `start` belong to the comparison window. When `start` is not a Monday, the bucket containing it mixes both windows. To build a window-level breakdown, keep the rows inside your window and sum `n_orders`, `net_revenue`, and `gross_profit` per `unit_quantity`. Do not sum the `pct_*` values; recompute shares from the summed counts.

> **`gross_profit` and `pct_profit_by_unit_quantity` are not COGS-suppressed here.** Every other analytics endpoint nulls profit metrics for a store with no COGS coverage, because the profit formula (`net_revenue - total_cost`) degenerates to `net_revenue` when `total_cogs` is `0`. This endpoint does not: the unit-mix rows carry no `pct_revenue_with_cogs` cell, so there is no coverage signal to suppress on, and `gross_profit` comes back as a raw revenue-shaped figure. Check COGS status with `POST /analytics/sitewide/snapshot` (its `cogs_configured` / `cogs_coverage_pct`) before reporting either field from this endpoint, and ignore both when `cogs_configured` is `false`. `n_orders`, `net_revenue`, `pct_orders_by_unit_quantity`, `pct_revenue_by_unit_quantity`, and the two distribution curves are unaffected.

This is the endpoint to use for an order-value distribution. The `histogram`, `kde`, and `cdf` fields on `POST /analytics/resource/{experienceId}` are always returned empty and are not populated there.

**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.
  - `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').
  - `orderValueDistribution` object, required: Order value distribution object containing `kernel_density_estimate` and `cumulative_distribution_function` arrays. Each point has an `x` (order value), `current_period`, and `previous_period` field. `current_period`/`previous_period` are `null` for every point of a period that had no orders in its window.
    - `kernel_density_estimate` object[], required: Kernel density estimation curve points for order value distribution. Each point has an `x` (order value), `current_period`, and `previous_period` field. A period with no orders is `null` at every point (no distribution to compare) rather than 0.
      - `x` number, required
      - `current_period` number, nullable, required
      - `previous_period` number, nullable, required
    - `cumulative_distribution_function` object[], required: Cumulative distribution function curve points for order value distribution. Each point has an `x` (order value), `current_period`, and `previous_period` field. A period with no orders is `null` at every point (no distribution to compare) rather than 0.
      - `x` number, required
      - `current_period` number, nullable, required
      - `previous_period` number, nullable, required
  - `orderBreakdown` object[], required: Breakdown of orders, revenue, and profit by number of units per order, bucketed weekly. One entry per (dt x unit_quantity): `dt` is the bucket start in the store's timezone ('YYYY-MM-DD HH:MM:SS'), and percentages are shares within that bucket. Buckets cover both the requested window and the equal-length comparison window before `start`. Each entry has dt, unit_quantity and metric values (n_orders, net_revenue, gross_profit as value objects, plus percentage equivalents).
    - `dt` string, required
    - `unit_quantity` number, required
    - `n_orders` object, required
      - `value` number, nullable, required
    - `net_revenue` object, required
      - `value` number, nullable, required
    - `gross_profit` object, required
      - `value` number, nullable, required
    - `pct_orders_by_unit_quantity` object, required
      - `value` number, nullable, required
    - `pct_revenue_by_unit_quantity` object, required
      - `value` number, nullable, required
    - `pct_profit_by_unit_quantity` object, required
      - `value` number, nullable, required

## Other responses

- `429`: Too Many Requests

---

[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/7b769b2f90b1?raw)
