Get sitewide conversion funnel
Retrieve the sitewide conversion funnel as a Sankey graph: visitors flow from entry point → landing page → second page → cart → checkout → conversion. The step-1 entry-point nodes default to device type (Mobile / Desktop); set entryPoint to pivot step 1 on traffic source, visitor type, or source site instead. Top-5 bucketing per step plus catch-all Other / Bounced rollups happen server-side; the wire format is already aggregated.
POST /v25-10-beta/analytics/sitewide/conversion-funnel
Request
| Field | Required | Type | Notes |
|---|---|---|---|
| start | no | ISO 8601 datetime string | Beginning of the analysis window. Defaults to the start of the day 30 days ago, in the store's timezone. Unlike the other sitewide endpoints, this default is day-aligned, not week-aligned. |
| end | no | ISO 8601 datetime string | End of the analysis window. Defaults to now. |
| filters | no | filters object | Shared sitewide filters that narrow the underlying dataset — deviceType, visitorType, sourceSitesOrChannels, countryCodes, currencyCodes, onlyProductIds, landingPageFilters (preferred; landingPage is deprecated), landingPageTypes, etc. See the Filters Reference for the full list. |
| entryPoint | no | string enum | Pivots the funnel's step-1 entry-point dimension — it controls which buckets are rendered at step 1, not which sessions are included. One of "device_type", "visitor_type", "source_channel", "source_site". Unrecognized values silently default to "device_type". Renamed from audience (see note below). See "Entry point vs. filters" below. |
| conversionFunnel | no | conversionFunnel object | Funnel-specific filters. Stage flags + single landing/second page-type pins. See "Funnel-specific filters" below. |
The conversionFunnel object
All funnel-specific filtering lives in a single optional conversionFunnel object. All fields are optional; combine any subset.
Stage flags (boolean) — narrow the funnel input to sessions that hit a behavioral stage:
- addedToCart — sessions that added at least one item to cart
- startedCheckout — sessions that started checkout
- converted — sessions that converted
- bounced — sessions that bounced (no second page)
- abandonedCart — added to cart but did not convert
- abandonedCheckout — started checkout but did not convert
- exitedBeforeAtc — exited before adding to cart
- viewedCollectionPage — viewed a collection page
- viewedProductPage — viewed a product detail page
Page-type pins (landing-page enum) — pin the funnel to a single journey:
- landingPageType — restrict to sessions whose landing page was this type
- secondPageType — restrict to sessions whose second page was this type
Supported page-type values: "PDP", "Collection", "Content", "Blog", "Homepage", "Search", "Cart", "Other".
Funnel-specific vs. shared filters
Two distinct layers of filtering, and they behave differently:
- filters.landingPageTypes (plural, array, inside the shared filters object) — narrows the underlying dataset to sessions starting on any of the selected page types. Same as the other /sitewide/* endpoints.
- conversionFunnel.landingPageType / conversionFunnel.secondPageType (singular) — pin the funnel itself to a specific journey, so a caller can see how the PDP → 2nd-page-PDP path converted in isolation.
- conversionFunnel stage flags (addedToCart, converted, etc.) — narrow the input population to sessions that hit a specific behavioral stage. Equivalent to the clickable node filters in the Intelligems dashboard.
conversionFunnel reuses the same schema the Intelligems dashboard sends internally, so the external contract matches the dashboard's funnel filtering exactly.
Entry point vs. filters
entryPoint and the shared filters look related but do completely different things. The simplest way to keep them straight:
filters change which sessions are included in the funnel. entryPoint changes which buckets are shown at step 1. They don't filter the same way — in fact, entryPoint doesn't filter at all.
Concrete contrast:
- filters.deviceType: "mobile" → the funnel is computed over only mobile sessions. Every step in the response reflects mobile-only counts. Desktop sessions are gone from the dataset entirely.
- entryPoint: "device_type" → the full dataset (mobile + desktop) is funneled, but step 1 of the Sankey is split into "Mobile" and "Desktop" nodes so you can see how each device cohort flows down. Nothing is filtered out.
Two questions, two different answers:
| Question | Use |
|---|---|
| "How does the funnel look for mobile traffic specifically?" | filters: { deviceType: "mobile" } |
| "How does the funnel split between Mobile and Desktop visitors at the entry point?" | entryPoint: "device_type" |
| "How does the funnel split by channel, restricted to mobile US traffic?" | both: entryPoint: "source_channel" + filters: … |
They compose without conflict — entryPoint controls the rendering of step 1, filters controls what data feeds into the funnel in the first place.
Supported entryPoint values
| entryPoint value | Step-1 nodes |
|---|---|
| "device_type" | "Mobile", "Desktop" |
| "visitor_type" | "New", "Returning" |
| "source_channel" | Channel buckets: "Paid Social", "Paid Search", "Direct", "Organic Search", "Email", "Affiliate", … with top-5 + "Other" rollup |
| "source_site" | Referrer display names ("Google", "Facebook", "Instagram", "Klaviyo", "TikTok", …) — not hostnames — with top-5 + "Other" rollup |
Reserved step-1 node names
- "Unknown" — emitted for any entryPoint when the session has no value for that dimension. It is a real bucket and counts toward the top-5 selection.
- "Misc" — emitted only for source_site and source_channel. Those two dimensions get the top-5 rollup, which reserves "Other" as the catch-all, so a session whose own taxonomy value is literally Other is renamed to "Misc" to keep the two distinct. device_type and visitor_type have no rollup and therefore never produce "Misc".
- "Other" — the top-5 rollup catch-all on source_site and source_channel only. Not a value any session carries.
These four mirror the Customer Journey chart's audience selector exactly. The shared AnalyticsAudienceType enum also has country_code and landing_page_full_path values, but the funnel intentionally excludes those — they're not surfaced in the dashboard's funnel view, so the external API and MCP do not expose them either.
Fallback on unrecognized values
If entryPoint is set to any string outside the four supported values (e.g., "country_code", "channel", "new_vs_returning", a typo), the request does not 400 — the value silently falls back to "device_type" and a warning is logged server-side. This is deliberate so that LLM-driven callers that guess slightly-wrong dimension names still get a sensible funnel back instead of an opaque validation error.
When entryPoint is omitted entirely, the funnel uses its built-in default step-1 split (the same default the dashboard's Customer Journey chart starts on).
Renamed from audience
This parameter was named audience in earlier v25-10-beta builds. It was renamed to entryPoint to disambiguate it from the audience segmentation parameter on the /analytics/sitewide/snapshot and /analytics/sitewide/timeseries endpoints — on the funnel it pivots step-1 entry-point nodes, it does not segment KPIs. A legacy audience key sent to this endpoint is now ignored (the funnel falls back to its default step-1 split rather than erroring), so update existing integrations to send entryPoint.
Response
Abbreviated example (one path through all six steps). Note every node referenced by a link appears in nodes, and step numbers are contiguous — a real response has more nodes/links per step:
{
"data": {
"nodes": [
{ "name": "Mobile", "step": 1, "value": 8000, "pct": 0.8 },
{ "name": "Desktop", "step": 1, "value": 2000, "pct": 0.2 },
{ "name": "Landing: PDP", "step": 2, "value": 6500, "pct": 0.65 },
{ "name": "Bounced", "step": 3, "value": 4200, "pct": 0.42 },
{ "name": "2nd Page: PDP", "step": 3, "value": 2300, "pct": 0.23 },
{
"name": "Exited before Add to Cart",
"step": 4,
"value": 1500,
"pct": 0.15
},
{ "name": "Added to Cart", "step": 4, "value": 800, "pct": 0.08 },
{ "name": "Started Checkout", "step": 5, "value": 480, "pct": 0.048 },
{ "name": "Abandoned Cart", "step": 5, "value": 320, "pct": 0.032 },
{ "name": "Converted", "step": 6, "value": 300, "pct": 0.03 },
{ "name": "Abandoned Checkout", "step": 6, "value": 180, "pct": 0.018 }
],
"links": [
{
"source": "Mobile",
"target": "Landing: PDP",
"step": 1,
"value": 5200
},
{
"source": "Desktop",
"target": "Landing: PDP",
"step": 1,
"value": 1300
},
{
"source": "Landing: PDP",
"target": "Bounced",
"step": 2,
"value": 4200
},
{
"source": "Landing: PDP",
"target": "2nd Page: PDP",
"step": 2,
"value": 2300
},
{
"source": "2nd Page: PDP",
"target": "Exited before Add to Cart",
"step": 3,
"value": 1500
},
{
"source": "2nd Page: PDP",
"target": "Added to Cart",
"step": 3,
"value": 800
},
{
"source": "Added to Cart",
"target": "Started Checkout",
"step": 4,
"value": 480
},
{
"source": "Added to Cart",
"target": "Abandoned Cart",
"step": 4,
"value": 320
},
{
"source": "Started Checkout",
"target": "Converted",
"step": 5,
"value": 300
},
{
"source": "Started Checkout",
"target": "Abandoned Checkout",
"step": 5,
"value": 180
}
]
}
}
Every node a link references is present in nodes, steps run 1→6 with no gaps, and each link.step equals its source node's step. pct values are all fractions of the step-1 total (10,000 here).
- nodes — one entry per labeled state at each step. Ordered by (step ascending, value descending).
- name — node label (e.g. "Mobile", "Landing: PDP", "Bounced", "Added to Cart").
- step — 1-indexed step position in the funnel.
- value — visitor count at this node.
- pct — share of step-1 visitors that reached this node, as a fraction in [0, 1] (not a percent).
- links — one entry per transition between adjacent step nodes. Ordered by (step ascending, value descending).
- source / target — node names on either end of the transition.
- step — step of the source node.
- value — visitor count traversing this link.
Server-side bucketing
At each step the server keeps the top 5 entries by traffic and rolls everything else into "Other". Two special node names are reserved:
- "Bounced" — sessions that ended before reaching a second page.
- "Landing: Other" / "2nd Page: Other" — catch-all buckets for low-volume landing or second-page types.
This is the same shape the Intelligems dashboard renders; there is no "unbucketed" mode.
Rate limits
Same rate limit as the other /analytics/sitewide/* endpoints. Aggregated, cacheable data — see the Rate Limiting Reference.
Rate Limit: 10 requests per 30s window, refilling 5 tokens every 30s.
Request
- Base URLhttps://api.intelligems.io
- AuthAPI key in header intelligems-access-token
- TypeScriptA function with typed inputs. Its response is checked against the schema.
Request body
Response
OK
Example response
{
"data": {
"nodes": [
{
"name": "Paid Search",
"step": 1,
"value": 10000,
"pct": 1
},
{
"name": "Landing Page",
"step": 2,
"value": 8500,
"pct": 0.85
},
{
"name": "Cart",
"step": 3,
"value": 3200,
"pct": 0.32
},
{
"name": "Checkout",
"step": 4,
"value": 1400,
"pct": 0.14
},
{
"name": "Converted",
"step": 5,
"value": 520,
"pct": 0.052
}
],
"links": [
{
"source": "Paid Search",
"target": "Landing Page",
"step": 1,
"value": 8500
},
{
"source": "Landing Page",
"target": "Cart",
"step": 2,
"value": 3200
},
{
"source": "Cart",
"target": "Checkout",
"step": 3,
"value": 1400
},
{
"source": "Checkout",
"target": "Converted",
"step": 4,
"value": 520
}
]
}
}Changes
No recorded changes to this operation across all 1 revision of this API.