{ "data": [ { "rank": 1, "product_id": "812345", "title": "Blue Tee" }, { "rank": 2, "product_id": "819921", "title": "Beach Towel" } ], "metric": "views", "window_days": 30, "refreshed_at": "2026-07-29T06:10:00Z", "note": "Entries are the connected store platform's product ids (e.g. the numeric Shopify product id) ranked best-first. Titles are resolved live from the connected store and are null when it cannot supply them; full product details are at GET /v1/products/{product_id}.", "pagination": { "page": 1, "per_page": 40, "total_count": 2, "total_pages": 1 }}
{
"error": {
"code": "unauthorized",
"message": "Bearer token is missing or invalid"
}
}
{
"error": {
"code": "insufficient_scope",
"message": "Token does not have the required scope"
}
}
{
"error": {
"code": "validation_failed",
"message": "One or more fields are invalid",
"details": [
{
"field": "email",
"message": "is required"
}
]
}
}
Retrieve your store’s top products ranked by views or sales over a
30, 60, or 90 day window, or all-time where the platform supports it.
Entries are the connected store platform’s product ids (e.g. the
numeric Shopify product id) ranked best-first. Each entry carries the
product title, resolved live from the connected store; it is null
when the store cannot supply it (no connected store, the product was
deleted, or the store API was unreachable). Full product details are
at GET /v1/products/{id}. Every response repeats this in an in-band
note.
Rankings are served from a daily-refreshed cache. refreshed_at is
the cache timestamp; null means this metric/window combination has
never been computed (as opposed to computed and empty) — the request
itself enqueues the background refresh that fills it, so retry after
a short wait.
Platform support differs by metric, and for views by window.
Windowed view rankings (window_days 30, 60, or 90) require a
connected Shopify store: dated product views are only tracked through
Shopify’s Web Pixel, so those windows return an empty ranking on every
other platform. All-time view rankings (window_days=0) come from the
store platform’s own view counter and are available for BigCommerce
only — BigCommerce exposes a per-product view count with no date
dimension, so it can be ranked all-time but never windowed. Shopify
has no such counter, so window_days=0 returns an empty ranking for a
Shopify-only store; a store connected to both platforms is ranked from
its BigCommerce counter.
The all-time ranking is built by scanning the BigCommerce catalog, and
that scan is capped at 25,000 products. On a larger catalog it covers
the products scanned rather than the whole catalog, so treat it as
approximate there.
sales is derived from synced order data and works for any store that
syncs orders to Privy (Shopify, BigCommerce, Wix, and orders submitted
through the API). There is no all-time sales bucket, so
metric=sales with window_days=0 is rejected.
{ "data": [ { "rank": 1, "product_id": "812345", "title": "Blue Tee" }, { "rank": 2, "product_id": "819921", "title": "Beach Towel" } ], "metric": "views", "window_days": 30, "refreshed_at": "2026-07-29T06:10:00Z", "note": "Entries are the connected store platform's product ids (e.g. the numeric Shopify product id) ranked best-first. Titles are resolved live from the connected store and are null when it cannot supply them; full product details are at GET /v1/products/{product_id}.", "pagination": { "page": 1, "per_page": 40, "total_count": 2, "total_pages": 1 }}
{
"error": {
"code": "unauthorized",
"message": "Bearer token is missing or invalid"
}
}
{
"error": {
"code": "insufficient_scope",
"message": "Token does not have the required scope"
}
}
{
"error": {
"code": "validation_failed",
"message": "One or more fields are invalid",
"details": [
{
"field": "email",
"message": "is required"
}
]
}
}
Target a subaccount instead of the main connected account.
Pass a subaccount id from get_account's subaccounts list. Only direct subaccounts
of the connected account are reachable — omit this for the main account itself.
Ranking metric. views availability depends on the store's platform and the requested window (see the operation description); sales works for any store that syncs orders to Privy.
When this ranking was last computed. null if it has never been computed. For the rolling windows the request enqueues the refresh that fills it. The all-time views ranking is computed only for BigCommerce stores that have configured a most-viewed dynamic product block, so null there means either the store's platform produces no all-time view counts or no such block exists yet.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Privy Knowledge Base","colors":{"primary":"#254E5A","light":"#E3E32B","dark":"#254E5A"},"logo":{"light":"https://mintcdn.com/privy/fGrkZt933tBjY_zl/logo/light.svg?fit=max\u0026auto=format\u0026n=fGrkZt933tBjY_zl\u0026q=85\u0026s=36a01db426b7c94fac423778765cd517","dark":"https://mintcdn.com/privy/fGrkZt933tBjY_zl/logo/dark.svg?fit=max\u0026auto=format\u0026n=fGrkZt933tBjY_zl\u0026q=85\u0026s=24576b53a928bf065f4a636ab8dc3431"},"favicon":"https://mintcdn.com/privy/fGrkZt933tBjY_zl/logo/favicon.svg?fit=max\u0026auto=format\u0026n=fGrkZt933tBjY_zl\u0026q=85\u0026s=9fee6eb5a3c74b929294365e07a3f01d","background":{"color":{"light":"#FFF","dark":"#0D1D23"}},"navbar":{"links":[{"href":"https://www.privy.com/pricing","label":"Pricing"},{"href":"mailto:support@privy.com","label":"Contact Support"}],"primary":{"type":"button","label":"Login","href":"https://dashboard.privy.com"}},"footer":{"socials":{"x":"https://x.com/privy","linkedin":"https://www.linkedin.com/company/privy"}},"seo":{"indexing":"all"},"fonts":{"heading":{"family":"Matter","weight":650,"source":"https://public-assets.privy.com/MatterStandard-VF.woff2","format":"woff2"},"body":{"family":"Matter","weight":400,"source":"https://public-assets.privy.com/MatterStandard-VF.woff2","format":"woff2"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"privy","hasAudioNarration":false,"actualSubdomain":"privy","customDomains":["help.privy.com"],"gitSource":{"type":"github","owner":"privy","repo":"mintlify-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"feedback":{"thumbs":true,"issues":true,"edits":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"REMOVE_BRANDING":{"status":"ENABLED"},"CONTEXTUAL_FEEDBACK":{"status":"ENABLED"},"CODE_SNIPPET_FEEDBACK":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6af3ac7069be62302954224f","clientVersion":"0.0.4111","searchFilterCounts":[{"language":"default","tag":"Learn","count":275},{"language":"default","tag":"Developer","count":49},{"language":"default","tag":"Integrations","count":30},{"language":"default","tag":"Strategy Guides","count":24},{"language":"default","tag":"Flows","count":18},{"language":"default","tag":"Account + Billing","count":18},{"language":"default","tag":"Contacts","count":17},{"language":"default","tag":"Displays","count":15},{"language":"default","tag":"Deliverability","count":11},{"language":"default","tag":"Content","count":10}]},"assistantConfig":{},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"@font-face{font-family:\"Matter\";src:url(\"https://public-assets.privy.com/MatterStandard-VF.woff2\") format(\"woff2\");font-display:swap;font-style:normal;font-weight:600}.mdx-content strong,.mdx-content b{font-weight:600}.mdx-content em,.mdx-content i{font-style:italic}"}],"page":{"pagePath":"docs/api-reference/list-top-products","slug":"/docs/api-reference/list-top-products","pageMetadata":{"title":"List top products","openapi":"openapi/privy-api.yaml GET /reports/top_products","description":"Retrieve your store's top products ranked by views or sales over a\n30, 60, or 90 day window, or all-time where the platform supports it.\n\nEntries are the connected store platform's product ids (e.g. the\nnumeric Shopify product id) ranked best-first. Each entry carries the\nproduct `title`, resolved live from the connected store; it is `null`\nwhen the store cannot supply it (no connected store, the product was\ndeleted, or the store API was unreachable). Full product details are\nat `GET /v1/products/{id}`. Every response repeats this in an in-band\n`note`.\n\nRankings are served from a daily-refreshed cache. `refreshed_at` is\nthe cache timestamp; `null` means this metric/window combination has\nnever been computed (as opposed to computed and empty) — the request\nitself enqueues the background refresh that fills it, so retry after\na short wait.\n\nPlatform support differs by metric, and for `views` by window.\nWindowed view rankings (`window_days` 30, 60, or 90) require a\nconnected Shopify store: dated product views are only tracked through\nShopify's Web Pixel, so those windows return an empty ranking on every\nother platform. All-time view rankings (`window_days=0`) come from the\nstore platform's own view counter and are available for BigCommerce\nonly — BigCommerce exposes a per-product view count with no date\ndimension, so it can be ranked all-time but never windowed. Shopify\nhas no such counter, so `window_days=0` returns an empty ranking for a\nShopify-only store; a store connected to both platforms is ranked from\nits BigCommerce counter.\n\nThe all-time ranking is built by scanning the BigCommerce catalog, and\nthat scan is capped at 25,000 products. On a larger catalog it covers\nthe products scanned rather than the whole catalog, so treat it as\napproximate there.\n\n`sales` is derived from synced order data and works for any store that\nsyncs orders to Privy (Shopify, BigCommerce, Wix, and orders submitted\nthrough the API). There is no all-time sales bucket, so\n`metric=sales` with `window_days=0` is rejected.\n\n**Required scope:** `reports_read`\n","href":"/docs/api-reference/list-top-products"},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n strong: \"strong\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.p, {\n children: \"Retrieve your store’s top products ranked by views or sales over a\\n30, 60, or 90 day window, or all-time where the platform supports it.\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Entries are the connected store platform’s product ids (e.g. the\\nnumeric Shopify product id) ranked best-first. Each entry carries the\\nproduct \", _jsx(_components.code, {\n children: \"title\"\n }), \", resolved live from the connected store; it is \", _jsx(_components.code, {\n children: \"null\"\n }), \"\\nwhen the store cannot supply it (no connected store, the product was\\ndeleted, or the store API was unreachable). Full product details are\\nat \", _jsx(_components.code, {\n children: \"GET /v1/products/{id}\"\n }), \". Every response repeats this in an in-band\\n\", _jsx(_components.code, {\n children: \"note\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Rankings are served from a daily-refreshed cache. \", _jsx(_components.code, {\n children: \"refreshed_at\"\n }), \" is\\nthe cache timestamp; \", _jsx(_components.code, {\n children: \"null\"\n }), \" means this metric/window combination has\\nnever been computed (as opposed to computed and empty) — the request\\nitself enqueues the background refresh that fills it, so retry after\\na short wait.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Platform support differs by metric, and for \", _jsx(_components.code, {\n children: \"views\"\n }), \" by window.\\nWindowed view rankings (\", _jsx(_components.code, {\n children: \"window_days\"\n }), \" 30, 60, or 90) require a\\nconnected Shopify store: dated product views are only tracked through\\nShopify’s Web Pixel, so those windows return an empty ranking on every\\nother platform. All-time view rankings (\", _jsx(_components.code, {\n children: \"window_days=0\"\n }), \") come from the\\nstore platform’s own view counter and are available for BigCommerce\\nonly — BigCommerce exposes a per-product view count with no date\\ndimension, so it can be ranked all-time but never windowed. Shopify\\nhas no such counter, so \", _jsx(_components.code, {\n children: \"window_days=0\"\n }), \" returns an empty ranking for a\\nShopify-only store; a store connected to both platforms is ranked from\\nits BigCommerce counter.\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"The all-time ranking is built by scanning the BigCommerce catalog, and\\nthat scan is capped at 25,000 products. On a larger catalog it covers\\nthe products scanned rather than the whole catalog, so treat it as\\napproximate there.\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n children: \"sales\"\n }), \" is derived from synced order data and works for any store that\\nsyncs orders to Privy (Shopify, BigCommerce, Wix, and orders submitted\\nthrough the API). There is no all-time sales bucket, so\\n\", _jsx(_components.code, {\n children: \"metric=sales\"\n }), \" with \", _jsx(_components.code, {\n children: \"window_days=0\"\n }), \" is rejected.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Required scope:\"\n }), \" \", _jsx(_components.code, {\n children: \"reports_read\"\n })]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"List top products","openapi":"openapi/privy-api.yaml GET /reports/top_products","description":"Retrieve your store's top products ranked by views or sales over a\n30, 60, or 90 day window, or all-time where the platform supports it.\n\nEntries are the connected store platform's product ids (e.g. the\nnumeric Shopify product id) ranked best-first. Each entry carries the\nproduct `title`, resolved live from the connected store; it is `null`\nwhen the store cannot supply it (no connected store, the product was\ndeleted, or the store API was unreachable). Full product details are\nat `GET /v1/products/{id}`. Every response repeats this in an in-band\n`note`.\n\nRankings are served from a daily-refreshed cache. `refreshed_at` is\nthe cache timestamp; `null` means this metric/window combination has\nnever been computed (as opposed to computed and empty) — the request\nitself enqueues the background refresh that fills it, so retry after\na short wait.\n\nPlatform support differs by metric, and for `views` by window.\nWindowed view rankings (`window_days` 30, 60, or 90) require a\nconnected Shopify store: dated product views are only tracked through\nShopify's Web Pixel, so those windows return an empty ranking on every\nother platform. All-time view rankings (`window_days=0`) come from the\nstore platform's own view counter and are available for BigCommerce\nonly — BigCommerce exposes a per-product view count with no date\ndimension, so it can be ranked all-time but never windowed. Shopify\nhas no such counter, so `window_days=0` returns an empty ranking for a\nShopify-only store; a store connected to both platforms is ranked from\nits BigCommerce counter.\n\nThe all-time ranking is built by scanning the BigCommerce catalog, and\nthat scan is capped at 25,000 products. On a larger catalog it covers\nthe products scanned rather than the whole catalog, so treat it as\napproximate there.\n\n`sales` is derived from synced order data and works for any store that\nsyncs orders to Privy (Shopify, BigCommerce, Wix, and orders submitted\nthrough the API). There is no all-time sales bucket, so\n`metric=sales` with `window_days=0` is rejected.\n\n**Required scope:** `reports_read`\n","href":"/docs/api-reference/list-top-products"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"operationId":"listTopProducts","summary":"List top products","description":"Retrieve your store's top products ranked by views or sales over a\n30, 60, or 90 day window, or all-time where the platform supports it.\n\nEntries are the connected store platform's product ids (e.g. the\nnumeric Shopify product id) ranked best-first. Each entry carries the\nproduct `title`, resolved live from the connected store; it is `null`\nwhen the store cannot supply it (no connected store, the product was\ndeleted, or the store API was unreachable). Full product details are\nat `GET /v1/products/{id}`. Every response repeats this in an in-band\n`note`.\n\nRankings are served from a daily-refreshed cache. `refreshed_at` is\nthe cache timestamp; `null` means this metric/window combination has\nnever been computed (as opposed to computed and empty) — the request\nitself enqueues the background refresh that fills it, so retry after\na short wait.\n\nPlatform support differs by metric, and for `views` by window.\nWindowed view rankings (`window_days` 30, 60, or 90) require a\nconnected Shopify store: dated product views are only tracked through\nShopify's Web Pixel, so those windows return an empty ranking on every\nother platform. All-time view rankings (`window_days=0`) come from the\nstore platform's own view counter and are available for BigCommerce\nonly — BigCommerce exposes a per-product view count with no date\ndimension, so it can be ranked all-time but never windowed. Shopify\nhas no such counter, so `window_days=0` returns an empty ranking for a\nShopify-only store; a store connected to both platforms is ranked from\nits BigCommerce counter.\n\nThe all-time ranking is built by scanning the BigCommerce catalog, and\nthat scan is capped at 25,000 products. On a larger catalog it covers\nthe products scanned rather than the whole catalog, so treat it as\napproximate there.\n\n`sales` is derived from synced order data and works for any store that\nsyncs orders to Privy (Shopify, BigCommerce, Wix, and orders submitted\nthrough the API). There is no all-time sales bucket, so\n`metric=sales` with `window_days=0` is rejected.\n\n**Required scope:** `reports_read`\n","tags":["Reports"],"security":["7d88f7ad-47cd-424f-a0aa-2590b8e20a04"],"parameters":["55d6f5c3-beed-43d0-8796-ed95cf3e1328","090c53ce-4fd5-4798-82a5-6b38bdc9b43b","09792f0e-c1d1-4c97-adf1-6acbaf0005bb","8eb35969-bbdd-40b0-a090-2f8265077a7e","3a752567-2e53-452e-838c-2a81ac9b20ca"],"responses":{"200":"7304e0a8-dfe8-4919-9cde-03dc98e9cf06","401":"10275b1d-13c7-4c5e-b68c-6c39fe313ee9","403":"aa08a9ff-a143-49a1-9214-96be3fcb26e6","422":"8c23586a-2ece-49e2-ac4d-99294c892ad2","429":"49d7bc21-35ef-4cb7-9918-767840b40b94"},"method":"get","type":"path","servers":["97f63e03-f020-41b7-a5b9-e312bbfed47d"],"path":"/reports/top_products","baseUrlOptions":["https://api.privy.com/v1"],"title":"List top products","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"55d6f5c3-beed-43d0-8796-ed95cf3e1328":{"name":"Privy-Account-Id","in":"header","required":false,"description":"Target a subaccount instead of the main connected account.\nPass a subaccount `id` from get_account's `subaccounts` list. Only direct subaccounts\nof the connected account are reachable — omit this for the main account itself.\n","schema":{"type":"string","isRequired":false,"description":"Target a subaccount instead of the main connected account.\nPass a subaccount `id` from get_account's `subaccounts` list. Only direct subaccounts\nof the connected account are reachable — omit this for the main account itself.\n","uniqueKey":"","typeLabel":"string"},"example":"S1U2B3A4C5C6T7"},"090c53ce-4fd5-4798-82a5-6b38bdc9b43b":{"name":"metric","in":"query","required":false,"description":"Ranking metric. `views` availability depends on the store's platform and the requested window (see the operation description); `sales` works for any store that syncs orders to Privy.","schema":{"type":"string","enum":["views","sales"],"default":"sales","isRequired":false,"description":"Ranking metric. `views` availability depends on the store's platform and the requested window (see the operation description); `sales` works for any store that syncs orders to Privy.","uniqueKey":"","typeLabel":"enum\u003cstring>"}},"09792f0e-c1d1-4c97-adf1-6acbaf0005bb":{"name":"window_days","in":"query","required":false,"description":"Ranking window in days. `0` means all-time, which is supported for `metric=views` on BigCommerce stores only and is rejected for `metric=sales`.","schema":{"type":"integer","enum":[0,30,60,90],"default":30,"isRequired":false,"description":"Ranking window in days. `0` means all-time, which is supported for `metric=views` on BigCommerce stores only and is rejected for `metric=sales`.","uniqueKey":"","typeLabel":"enum\u003cinteger>"}},"8eb35969-bbdd-40b0-a090-2f8265077a7e":{"name":"page","in":"query","description":"Page number (starts at 1).","schema":{"type":"integer","default":1,"minimum":1,"description":"Page number (starts at 1).","uniqueKey":"","typeLabel":"integer"},"example":1},"3a752567-2e53-452e-838c-2a81ac9b20ca":{"name":"per_page","in":"query","description":"Number of results per page. Values outside 10–100 are clamped to the nearest bound.","schema":{"type":"integer","default":40,"minimum":10,"maximum":100,"description":"Number of results per page. Values outside 10–100 are clamped to the nearest bound.","uniqueKey":"","typeLabel":"integer"},"example":40}},"responses":{"7304e0a8-dfe8-4919-9cde-03dc98e9cf06":{"description":"The ranked product ids for the requested metric and window.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"rank":{"type":"integer","description":"1-based rank, best first.","uniqueKey":"data.items.[INDEX].rank","typeLabel":"integer"},"product_id":{"type":"string","description":"The connected store platform's product id (e.g. the numeric Shopify product id).","uniqueKey":"data.items.[INDEX].product_id","typeLabel":"string"},"title":{"oneOf":[{"type":"string","description":"Product title resolved live from the connected store; `null` when the store cannot supply it.","uniqueKey":"data.items.[INDEX].title.oneOf.0","typeLabel":"string"},{"type":"null","description":"Product title resolved live from the connected store; `null` when the store cannot supply it.","uniqueKey":"data.items.[INDEX].title.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.items.[INDEX].title","typeLabel":"string | null"}},"uniqueKey":"data.items.[INDEX]","typeLabel":"object"},"uniqueKey":"data","typeLabel":"object[]"},"metric":{"type":"string","enum":["views","sales"],"uniqueKey":"metric","typeLabel":"enum\u003cstring>"},"window_days":{"type":"integer","enum":[0,30,60,90],"description":"The window this ranking covers. `0` means all-time.","uniqueKey":"window_days","typeLabel":"enum\u003cinteger>"},"refreshed_at":{"oneOf":[{"type":"string","format":"date-time","description":"When this ranking was last computed. `null` if it has never been computed. For the rolling windows the request enqueues the refresh that fills it. The all-time views ranking is computed only for BigCommerce stores that have configured a most-viewed dynamic product block, so `null` there means either the store's platform produces no all-time view counts or no such block exists yet.","uniqueKey":"refreshed_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When this ranking was last computed. `null` if it has never been computed. For the rolling windows the request enqueues the refresh that fills it. The all-time views ranking is computed only for BigCommerce stores that have configured a most-viewed dynamic product block, so `null` there means either the store's platform produces no all-time view counts or no such block exists yet.","uniqueKey":"refreshed_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"refreshed_at","typeLabel":"string\u003cdate-time> | null"},"note":{"type":"string","description":"Fixed caveat that entries are store product ids with live-resolved titles, and full details live at GET /v1/products/{id}.","uniqueKey":"note","typeLabel":"string"},"pagination":{"type":"object","properties":{"page":{"type":"integer","example":1,"uniqueKey":"pagination.page","typeLabel":"integer"},"per_page":{"type":"integer","example":25,"uniqueKey":"pagination.per_page","typeLabel":"integer"},"total_count":{"type":"integer","example":142,"uniqueKey":"pagination.total_count","typeLabel":"integer"},"total_pages":{"type":"integer","example":6,"uniqueKey":"pagination.total_pages","typeLabel":"integer"}},"uniqueKey":"pagination","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"data":[{"rank":1,"product_id":"812345","title":"Blue Tee"},{"rank":2,"product_id":"819921","title":"Beach Towel"}],"metric":"views","window_days":30,"refreshed_at":"2026-07-29T06:10:00Z","note":"Entries are the connected store platform's product ids (e.g. the numeric Shopify product id) ranked best-first. Titles are resolved live from the connected store and are null when it cannot supply them; full product details are at GET /v1/products/{product_id}.","pagination":{"page":1,"per_page":40,"total_count":2,"total_pages":1}},"examples":{"Example":{"title":"Example","value":{"data":[{"rank":1,"product_id":"812345","title":"Blue Tee"},{"rank":2,"product_id":"819921","title":"Beach Towel"}],"metric":"views","window_days":30,"refreshed_at":"2026-07-29T06:10:00Z","note":"Entries are the connected store platform's product ids (e.g. the numeric Shopify product id) ranked best-first. Titles are resolved live from the connected store and are null when it cannot supply them; full product details are at GET /v1/products/{product_id}.","pagination":{"page":1,"per_page":40,"total_count":2,"total_pages":1}}}},"exampleType":"examples"}},"exampleType":"examples"},"10275b1d-13c7-4c5e-b68c-6c39fe313ee9":{"description":"Missing or invalid bearer token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_client","invalid_scope","unauthorized","insufficient_scope","forbidden","paid_plan_required","api_access_required","segment_builder_required","not_found","no_connected_store","conflict","contacts_not_ready","validation_failed","idempotency_key_reused","rate_limited","store_unavailable","store_rate_limited","not_a_draft","design_changed","sms_missing","email_missing","ab_test_draft","idempotency_key_reused","template_unavailable","design_unavailable","render_failed"],"example":"validation_failed","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","example":"One or more fields are invalid","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"email","uniqueKey":"error.details.items.[INDEX].field","typeLabel":"string"},"message":{"type":"string","example":"is required","uniqueKey":"error.details.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"uniqueKey":"error.details","typeLabel":"object[]"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"unauthorized","message":"Bearer token is missing or invalid"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"unauthorized","message":"Bearer token is missing or invalid"}}}},"exampleType":"examples"}},"exampleType":"examples"},"aa08a9ff-a143-49a1-9214-96be3fcb26e6":{"description":"`insufficient_scope` when the token lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_client","invalid_scope","unauthorized","insufficient_scope","forbidden","paid_plan_required","api_access_required","segment_builder_required","not_found","no_connected_store","conflict","contacts_not_ready","validation_failed","idempotency_key_reused","rate_limited","store_unavailable","store_rate_limited","not_a_draft","design_changed","sms_missing","email_missing","ab_test_draft","idempotency_key_reused","template_unavailable","design_unavailable","render_failed"],"example":"validation_failed","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","example":"One or more fields are invalid","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"email","uniqueKey":"error.details.items.[INDEX].field","typeLabel":"string"},"message":{"type":"string","example":"is required","uniqueKey":"error.details.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"uniqueKey":"error.details","typeLabel":"object[]"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"insufficient_scope","message":"Token does not have the required scope"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"insufficient_scope","message":"Token does not have the required scope"}}}},"exampleType":"examples"}},"exampleType":"examples"},"8c23586a-2ece-49e2-ac4d-99294c892ad2":{"description":"One or more fields failed validation.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_client","invalid_scope","unauthorized","insufficient_scope","forbidden","paid_plan_required","api_access_required","segment_builder_required","not_found","no_connected_store","conflict","contacts_not_ready","validation_failed","idempotency_key_reused","rate_limited","store_unavailable","store_rate_limited","not_a_draft","design_changed","sms_missing","email_missing","ab_test_draft","idempotency_key_reused","template_unavailable","design_unavailable","render_failed"],"example":"validation_failed","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","example":"One or more fields are invalid","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"email","uniqueKey":"error.details.items.[INDEX].field","typeLabel":"string"},"message":{"type":"string","example":"is required","uniqueKey":"error.details.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"uniqueKey":"error.details","typeLabel":"object[]"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"validation_failed","message":"One or more fields are invalid","details":[{"field":"email","message":"is required"}]}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"validation_failed","message":"One or more fields are invalid","details":[{"field":"email","message":"is required"}]}}}},"exampleType":"examples"}},"exampleType":"examples"},"49d7bc21-35ef-4cb7-9918-767840b40b94":{"description":"Rate limit exceeded. Retry after the specified time.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":42},"X-RateLimit-Limit-Minute":{"description":"Maximum requests allowed per minute.","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining-Minute":{"description":"Requests remaining in the current minute window.","schema":{"type":"integer"},"example":0},"X-RateLimit-Reset-Minute":{"description":"Unix timestamp when the minute window resets.","schema":{"type":"integer"},"example":1711929600},"X-RateLimit-Limit-Day":{"description":"Maximum requests allowed per day.","schema":{"type":"integer"},"example":10000},"X-RateLimit-Remaining-Day":{"description":"Requests remaining in the current day window.","schema":{"type":"integer"},"example":9500},"X-RateLimit-Reset-Day":{"description":"Unix timestamp when the day window resets.","schema":{"type":"integer"},"example":1712016000}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_client","invalid_scope","unauthorized","insufficient_scope","forbidden","paid_plan_required","api_access_required","segment_builder_required","not_found","no_connected_store","conflict","contacts_not_ready","validation_failed","idempotency_key_reused","rate_limited","store_unavailable","store_rate_limited","not_a_draft","design_changed","sms_missing","email_missing","ab_test_draft","idempotency_key_reused","template_unavailable","design_unavailable","render_failed"],"example":"validation_failed","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","example":"One or more fields are invalid","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"email","uniqueKey":"error.details.items.[INDEX].field","typeLabel":"string"},"message":{"type":"string","example":"is required","uniqueKey":"error.details.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"uniqueKey":"error.details","typeLabel":"object[]"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"rate_limited","message":"Rate limit exceeded"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"rate_limited","message":"Rate limit exceeded"}}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"7d88f7ad-47cd-424f-a0aa-2590b8e20a04":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token or OAuth access token","description":"Send either an API token or an OAuth access token as\n`Authorization: Bearer \u003ctoken>`. See the Authentication page for details.\n","scopes":[],"schemeName":"bearerAuth"}}},"servers":{"97f63e03-f020-41b7-a5b9-e312bbfed47d":{"url":"https://api.privy.com/v1","description":"Production"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","bearerFormat":"API token or OAuth access token","description":"Send either an API token or an OAuth access token as\n`Authorization: Bearer \u003ctoken>`. See the Authentication page for details.\n","scopes":[],"schemeName":"bearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Send either an API token or an OAuth access token as\n`Authorization: Bearer \u003ctoken>`. See the Authentication page for details.\n","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"bearerAuth","name":"Authorization"}],"title":"bearerAuth"}]},"originalFileLocation":"openapi/privy-api.yaml"},"subdomain":"privy","siteName":"Privy Knowledge Base","title":"List top products - Privy Knowledge Base","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-22T23:08:30.075Z","originalFileLocation":"docs/api-reference/list-top-products.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Retrieve your store\u0026#x27;s top products ranked by views or sales over a 30, 60, or 90 day window, or all-time where the platform supports it. Entries are the connected store platform\u0026#x27;s product ids (e.g. the numeric Shopify product id) ranked best-first. Each entry carries the product title, resolved live from the connected store; it is null when the store cannot supply it (no connected store, the product was deleted, or the store API was unreachable). Full product details are at GET /v1/products/{id}. Every response repeats this in an in-band note. Rankings are served from a daily-refreshed cache. refreshed_at is the cache timestamp; null means this metric/window combination has never been computed (as opposed to computed and empty) — the request itself enqueues the background refresh that fills it, so retry after a short wait. Platform support differs by metric, and for views by window. Windowed view rankings (window_days 30, 60, or 90) require a connected Shopify store: dated product views are only tracked through Shopify\u0026#x27;s Web Pixel, so those windows return an empty ranking on every other platform. All-time view rankings (window_days=0) come from the store platform\u0026#x27;s own view counter and are available for BigCommerce only — BigCommerce exposes a per-product view count with no date dimension, so it can be ranked all-time but never windowed. Shopify has no such counter, so window_days=0 returns an empty ranking for a Shopify-only store; a store connected to both platforms is ranked from its BigCommerce counter. The all-time ranking is built by scanning the BigCommerce catalog, and that scan is capped at 25,000 products. On a larger catalog it covers the products scanned rather than the whole catalog, so treat it as approximate there. sales is derived from synced order data and works for any store that syncs orders to Privy (Shopify, BigCommerce, Wix, and orders submitted through the API). There is no all-time sales bucket, so metric=sales with window_days=0 is rejected. Required scope: reports_read\">\u003cmeta data-mint-head name=\"application-name\" content=\"Privy Knowledge Base\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"List top products - Privy Knowledge Base\">\u003cmeta data-mint-head property=\"og:description\" content=\"Retrieve your store\u0026#x27;s top products ranked by views or sales over a 30, 60, or 90 day window, or all-time where the platform supports it. Entries are the connected store platform\u0026#x27;s product ids (e.g. the numeric Shopify product id) ranked best-first. Each entry carries the product title, resolved live from the connected store; it is null when the store cannot supply it (no connected store, the product was deleted, or the store API was unreachable). Full product details are at GET /v1/products/{id}. Every response repeats this in an in-band note. Rankings are served from a daily-refreshed cache. refreshed_at is the cache timestamp; null means this metric/window combination has never been computed (as opposed to computed and empty) — the request itself enqueues the background refresh that fills it, so retry after a short wait. Platform support differs by metric, and for views by window. Windowed view rankings (window_days 30, 60, or 90) require a connected Shopify store: dated product views are only tracked through Shopify\u0026#x27;s Web Pixel, so those windows return an empty ranking on every other platform. All-time view rankings (window_days=0) come from the store platform\u0026#x27;s own view counter and are available for BigCommerce only — BigCommerce exposes a per-product view count with no date dimension, so it can be ranked all-time but never windowed. Shopify has no such counter, so window_days=0 returns an empty ranking for a Shopify-only store; a store connected to both platforms is ranked from its BigCommerce counter. The all-time ranking is built by scanning the BigCommerce catalog, and that scan is capped at 25,000 products. On a larger catalog it covers the products scanned rather than the whole catalog, so treat it as approximate there. sales is derived from synced order data and works for any store that syncs orders to Privy (Shopify, BigCommerce, Wix, and orders submitted through the API). There is no all-time sales bucket, so metric=sales with window_days=0 is rejected. Required scope: reports_read\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Privy Knowledge Base\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://help.privy.com/docs/api-reference/list-top-products\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://privy.mintlify.site/_mintlify/api/og/v2?division=Reports\u0026amp;title=List+top+products\u0026amp;description=Retrieve+your+store%27s+top+products+ranked+by+views+or+sales+over+a%0A30%2C+60%2C+or+90+day+window%2C+or+all-time+where+the+platform+supports+it.%0A%0AEntries+are+the+connec\u0026amp;theme=a5dbdd3119e247d04186b21c\u0026amp;signature=458a6676dd75f2dd04e8cb466fa9e401b1fe328a14fa3335692b49d6ebb094f8\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"List top products - Privy Knowledge Base\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Retrieve your store\u0026#x27;s top products ranked by views or sales over a 30, 60, or 90 day window, or all-time where the platform supports it. Entries are the connected store platform\u0026#x27;s product ids (e.g. the numeric Shopify product id) ranked best-first. Each entry carries the product title, resolved live from the connected store; it is null when the store cannot supply it (no connected store, the product was deleted, or the store API was unreachable). Full product details are at GET /v1/products/{id}. Every response repeats this in an in-band note. Rankings are served from a daily-refreshed cache. refreshed_at is the cache timestamp; null means this metric/window combination has never been computed (as opposed to computed and empty) — the request itself enqueues the background refresh that fills it, so retry after a short wait. Platform support differs by metric, and for views by window. Windowed view rankings (window_days 30, 60, or 90) require a connected Shopify store: dated product views are only tracked through Shopify\u0026#x27;s Web Pixel, so those windows return an empty ranking on every other platform. All-time view rankings (window_days=0) come from the store platform\u0026#x27;s own view counter and are available for BigCommerce only — BigCommerce exposes a per-product view count with no date dimension, so it can be ranked all-time but never windowed. Shopify has no such counter, so window_days=0 returns an empty ranking for a Shopify-only store; a store connected to both platforms is ranked from its BigCommerce counter. The all-time ranking is built by scanning the BigCommerce catalog, and that scan is capped at 25,000 products. On a larger catalog it covers the products scanned rather than the whole catalog, so treat it as approximate there. sales is derived from synced order data and works for any store that syncs orders to Privy (Shopify, BigCommerce, Wix, and orders submitted through the API). There is no all-time sales bucket, so metric=sales with window_days=0 is rejected. Required scope: reports_read\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://privy.mintlify.site/_mintlify/api/og/v2?division=Reports\u0026amp;title=List+top+products\u0026amp;description=Retrieve+your+store%27s+top+products+ranked+by+views+or+sales+over+a%0A30%2C+60%2C+or+90+day+window%2C+or+all-time+where+the+platform+supports+it.%0A%0AEntries+are+the+connec\u0026amp;theme=a5dbdd3119e247d04186b21c\u0026amp;signature=458a6676dd75f2dd04e8cb466fa9e401b1fe328a14fa3335692b49d6ebb094f8\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Privy Knowledge Base\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#254E5A\">\u003clink data-mint-head rel=\"canonical\" href=\"https://help.privy.com/docs/api-reference/list-top-products\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/api-reference/list-top-products.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://help.privy.com/#organization\",\"name\":\"Privy Knowledge Base\",\"url\":\"https://help.privy.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/privy/fGrkZt933tBjY_zl/logo/light.svg?fit=max\u0026auto=format\u0026n=fGrkZt933tBjY_zl\u0026q=85\u0026s=36a01db426b7c94fac423778765cd517\"}},{\"@type\":\"WebSite\",\"@id\":\"https://help.privy.com#website\",\"name\":\"Privy Knowledge Base\",\"url\":\"https://help.privy.com\",\"publisher\":{\"@id\":\"https://help.privy.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://help.privy.com/docs/api-reference/list-top-products#webpage\",\"url\":\"https://help.privy.com/docs/api-reference/list-top-products\",\"name\":\"List top products\",\"description\":\"Retrieve your store's top products ranked by views or sales over a 30, 60, or 90 day window, or all-time where the platform supports it. Entries are the connected store platform's product ids (e.g. the numeric Shopify product id) ranked best-first. Each entry carries the product title, resolved live from the connected store; it is null when the store cannot supply it (no connected store, the product was deleted, or the store API was unreachable). Full product details are at GET /v1/products/{id}. Every response repeats this in an in-band note. Rankings are served from a daily-refreshed cache. refreshed_at is the cache timestamp; null means this metric/window combination has never been computed (as opposed to computed and empty) — the request itself enqueues the background refresh that fills it, so retry after a short wait. Platform support differs by metric, and for views by window. Windowed view rankings (window_days 30, 60, or 90) require a connected Shopify store: dated product views are only tracked through Shopify's Web Pixel, so those windows return an empty ranking on every other platform. All-time view rankings (window_days=0) come from the store platform's own view counter and are available for BigCommerce only — BigCommerce exposes a per-product view count with no date dimension, so it can be ranked all-time but never windowed. Shopify has no such counter, so window_days=0 returns an empty ranking for a Shopify-only store; a store connected to both platforms is ranked from its BigCommerce counter. The all-time ranking is built by scanning the BigCommerce catalog, and that scan is capped at 25,000 products. On a larger catalog it covers the products scanned rather than the whole catalog, so treat it as approximate there. sales is derived from synced order data and works for any store that syncs orders to Privy (Shopify, BigCommerce, Wix, and orders submitted through the API). There is no all-time sales bucket, so metric=sales with window_days=0 is rejected. Required scope: reports_read\",\"dateModified\":\"2026-10-22T23:08:30.075Z\",\"isPartOf\":{\"@id\":\"https://help.privy.com#website\"},\"breadcrumb\":{\"@id\":\"https://help.privy.com/docs/api-reference/list-top-products#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://help.privy.com/docs/api-reference/list-top-products#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Reports\",\"item\":\"https://help.privy.com/docs/api-reference/get-report-summary\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"List top products\",\"item\":\"https://help.privy.com/docs/api-reference/list-top-products\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://help.privy.com/docs/api-reference/list-top-products#apireference\",\"headline\":\"List top products\",\"name\":\"List top products\",\"description\":\"Retrieve your store's top products ranked by views or sales over a 30, 60, or 90 day window, or all-time where the platform supports it. Entries are the connected store platform's product ids (e.g. the numeric Shopify product id) ranked best-first. Each entry carries the product title, resolved live from the connected store; it is null when the store cannot supply it (no connected store, the product was deleted, or the store API was unreachable). Full product details are at GET /v1/products/{id}. Every response repeats this in an in-band note. Rankings are served from a daily-refreshed cache. refreshed_at is the cache timestamp; null means this metric/window combination has never been computed (as opposed to computed and empty) — the request itself enqueues the background refresh that fills it, so retry after a short wait. Platform support differs by metric, and for views by window. Windowed view rankings (window_days 30, 60, or 90) require a connected Shopify store: dated product views are only tracked through Shopify's Web Pixel, so those windows return an empty ranking on every other platform. All-time view rankings (window_days=0) come from the store platform's own view counter and are available for BigCommerce only — BigCommerce exposes a per-product view count with no date dimension, so it can be ranked all-time but never windowed. Shopify has no such counter, so window_days=0 returns an empty ranking for a Shopify-only store; a store connected to both platforms is ranked from its BigCommerce counter. The all-time ranking is built by scanning the BigCommerce catalog, and that scan is capped at 25,000 products. On a larger catalog it covers the products scanned rather than the whole catalog, so treat it as approximate there. sales is derived from synced order data and works for any store that syncs orders to Privy (Shopify, BigCommerce, Wix, and orders submitted through the API). There is no all-time sales bucket, so metric=sales with window_days=0 is rejected. Required scope: reports_read\",\"url\":\"https://help.privy.com/docs/api-reference/list-top-products\",\"mainEntityOfPage\":{\"@id\":\"https://help.privy.com/docs/api-reference/list-top-products#webpage\"},\"dateModified\":\"2026-10-22T23:08:30.075Z\",\"publisher\":{\"@id\":\"https://help.privy.com/#organization\"},\"isPartOf\":{\"@id\":\"https://help.privy.com#website\"}}]}\u003c/script>","agentPointerHref":"/docs/api-reference/list-top-products.md","siteName":"Privy Knowledge Base","nav":{"global":null,"tabs":[{"tab":"Learn","icon":"house","pages":[{"title":"Learn","href":"/docs/learn/home"}]},{"tab":"Developer","icon":"square-terminal","groups":[{"group":"API Reference","pages":[{"title":"API Overview","sidebarTitle":"Overview","icon":"book-open","href":"/docs/api-reference/overview"},{"title":"Authentication","sidebarTitle":"Authentication","icon":"lock","href":"/docs/api-reference/authentication"},{"title":"API Tokens","sidebarTitle":"API Tokens","icon":"key","href":"/docs/api-reference/api-tokens"},{"title":"Rate Limits","sidebarTitle":"Rate Limits","icon":"gauge","href":"/docs/api-reference/rate-limits"},{"title":"Errors","sidebarTitle":"Errors","icon":"triangle-exclamation","href":"/docs/api-reference/errors"},{"title":"API Changelog","sidebarTitle":"Changelog","icon":"clock-rotate-left","href":"/docs/api-reference/changelog"}]},{"group":"Account","pages":[{"title":"Get account","openapi":"openapi/privy-api.yaml GET /account","href":"/docs/api-reference/get-account"},{"title":"Get account setup","openapi":"openapi/privy-api.yaml GET /account/setup","href":"/docs/api-reference/get-account-setup"}]},{"group":"Contacts","pages":[{"title":"List contacts","openapi":"openapi/privy-api.yaml GET /contacts","href":"/docs/api-reference/list-contacts"},{"title":"Get a contact","openapi":"openapi/privy-api.yaml GET /contacts/{id}","href":"/docs/api-reference/get-contact"},{"title":"Create a contact","openapi":"openapi/privy-api.yaml POST /contacts","href":"/docs/api-reference/create-contact"},{"title":"Update a contact","openapi":"openapi/privy-api.yaml PATCH /contacts/{id}","href":"/docs/api-reference/update-contact"},{"title":"Delete a contact","openapi":"openapi/privy-api.yaml DELETE /contacts/{id}","href":"/docs/api-reference/delete-contact"},{"title":"List a contact's activity","openapi":"openapi/privy-api.yaml GET /contacts/{id}/events","href":"/docs/api-reference/list-contact-activity"}]},{"group":"Imports","pages":[{"title":"List contact imports","openapi":"openapi/privy-api.yaml GET /imports","href":"/docs/api-reference/list-imports"},{"title":"Get a contact import","openapi":"openapi/privy-api.yaml GET /imports/{id}","href":"/docs/api-reference/get-import"}]},{"group":"Tags","pages":[{"title":"List tags","openapi":"openapi/privy-api.yaml GET /tags","href":"/docs/api-reference/list-tags"},{"title":"Get a tag","openapi":"openapi/privy-api.yaml GET /tags/{id}","href":"/docs/api-reference/get-tag"}]},{"group":"Campaigns","pages":[{"title":"List campaigns","openapi":"openapi/privy-api.yaml GET /campaigns","href":"/docs/api-reference/list-campaigns"},{"title":"Get a campaign","openapi":"openapi/privy-api.yaml GET /campaigns/{id}","href":"/docs/api-reference/get-campaign"}]},{"group":"Displays","pages":[{"title":"List displays","openapi":"openapi/privy-api.yaml GET /displays","href":"/docs/api-reference/list-displays"},{"title":"Get a display","openapi":"openapi/privy-api.yaml GET /displays/{id}","href":"/docs/api-reference/get-display"}]},{"group":"Coupons","pages":[{"title":"List coupons","openapi":"openapi/privy-api.yaml GET /coupons","href":"/docs/api-reference/list-coupons"},{"title":"Get a coupon","openapi":"openapi/privy-api.yaml GET /coupons/{id}","href":"/docs/api-reference/get-coupon"},{"title":"Check a coupon code","openapi":"openapi/privy-api.yaml GET /coupons/{id}/codes/{code}","href":"/docs/api-reference/check-coupon-code"}]},{"group":"Reports","pages":[{"title":"Get business report summary","openapi":"openapi/privy-api.yaml GET /reports/summary","href":"/docs/api-reference/get-report-summary"},{"title":"List campaign performance","openapi":"openapi/privy-api.yaml GET /reports/campaigns","href":"/docs/api-reference/list-campaign-performance"},{"title":"Get campaign performance","openapi":"openapi/privy-api.yaml GET /reports/campaigns/{campaign_id}","href":"/docs/api-reference/get-campaign-performance"},{"title":"List flow performance","openapi":"openapi/privy-api.yaml GET /reports/flows","href":"/docs/api-reference/list-flow-performance"},{"title":"Get flow performance","openapi":"openapi/privy-api.yaml GET /reports/flows/{flow_id}","href":"/docs/api-reference/get-flow-performance"},{"title":"List display performance","openapi":"openapi/privy-api.yaml GET /reports/displays","href":"/docs/api-reference/list-display-performance"},{"title":"Get display performance","openapi":"openapi/privy-api.yaml GET /reports/displays/{display_id}","description":"The full performance stat set for one display over a period, including\naverage order value and, when the display has run an A/B test, per-variation\nparticipants, conversions, and conversion rates.\n\nAsk this per display rather than hunting the leaderboard: unlike\n`/v1/reports/displays` it reports zeroed stats for a quiet display instead\nof leaving it out. The display's own configuration — triggers, schedule,\nstatus — is `/v1/displays/{id}`, keyed on the same identifier.\n\n**Required scope:** `reports_read`\n","href":"/docs/api-reference/get-display-performance"},{"title":"List top products","openapi":"openapi/privy-api.yaml GET /reports/top_products","href":"/docs/api-reference/list-top-products"}]},{"group":"Flows","pages":[{"title":"List flows","openapi":"openapi/privy-api.yaml GET /flows","description":"Retrieve a paginated list of your automation flows, including each flow's trigger and steps.\nUse `GET /v1/flows/{id}` for a flow's full configuration — entry frequency,\nflow filters, exit criteria, and the node branch graph.\n\nConfiguration only — no performance, and no membership. Flow results and\nthe live enrollment count both come from `/v1/reports/flows`, which lists\nevery flow, so pair the two rather than expecting stats here.\n\n**Required scope:** `flows_read`\n","href":"/docs/api-reference/list-flows"},{"title":"Get a flow","openapi":"openapi/privy-api.yaml GET /flows/{id}","href":"/docs/api-reference/get-flow"}]},{"group":"Segments","pages":[{"title":"List segments","openapi":"openapi/privy-api.yaml GET /segments","href":"/docs/api-reference/list-segments"},{"title":"Get a segment","openapi":"openapi/privy-api.yaml GET /segments/{id}","href":"/docs/api-reference/get-segment"},{"title":"List a segment's contacts","openapi":"openapi/privy-api.yaml GET /segments/{id}/contacts","href":"/docs/api-reference/list-segment-contacts"}]},{"group":"Orders","pages":[{"title":"Order placed","openapi":"openapi/privy-api.yaml POST /orders/placed","href":"/docs/api-reference/order-placed"},{"title":"List orders","openapi":"openapi/privy-api.yaml GET /orders","href":"/docs/api-reference/list-orders"},{"title":"Get an order","openapi":"openapi/privy-api.yaml GET /orders/{order_id}","href":"/docs/api-reference/get-order"}]},{"group":"Products","pages":[{"title":"List products","openapi":"openapi/privy-api.yaml GET /products","href":"/docs/api-reference/list-products"},{"title":"Get a product","openapi":"openapi/privy-api.yaml GET /products/{id}","href":"/docs/api-reference/get-product"},{"title":"List product collections","openapi":"openapi/privy-api.yaml GET /product_collections","href":"/docs/api-reference/list-product-collections"},{"title":"Get a product collection","openapi":"openapi/privy-api.yaml GET /product_collections/{id}","href":"/docs/api-reference/get-product-collection"},{"title":"List a collection's products","openapi":"openapi/privy-api.yaml GET /product_collections/{id}/products","href":"/docs/api-reference/list-collection-products"},{"title":"List a product's collections","openapi":"openapi/privy-api.yaml GET /products/{id}/collections","href":"/docs/api-reference/list-collections-for-product"}]},{"group":"Events","pages":[{"title":"Ingest an event","openapi":"openapi/privy-api.yaml POST /events","href":"/docs/api-reference/ingest-event"},{"title":"Send cart events from your storefront","sidebarTitle":"Browser events","href":"/docs/api-reference/browser-events"}]}]}]},"basePath":"","title":"List top products - Privy Knowledge Base","buildId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","deploymentId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-CybtLBIt.js","utils-BMLj2fvV.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-B6In562Y.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-Dr8Mfhp9.js","snippetPresets-2rmQvMVl.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-WMqJYdZj.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-CJ-MlPHu.js","shallow-dY3TMRCk.js","getApiPlaygroundDisplay-v-1B2bKm.js","CodeSnippet-BDhiTB7U.js","CodeSnippets-D9hnzQcS.js","Page-C4GwDT3_.js","getPastedJson-Th2V45jI.js","icon-BQXch1W9.js","MethodPill-BCqUneP3.js","DuplicateIcon-Q_-bhurZ.js","createIcon-DUjLHRqp.js","DynamicMarkdown-B-f2cqXQ.js","SectionHeading-Da5NsV4v.js","axios-vUo_bRtp.js","Markdown-D13FWkIM.js","clsx-D3Isdib3.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-C-XZBk9h.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink--qIqmmVG.js"]}