The business-level performance rollup for a period: signups, new
subscribers, attributed revenue and orders, engagement rates, and
business-wide order and revenue totals for context. Pass
compare=previous_period to add previous-period values and typed
change deltas to every metric.
attributed_revenue and attributed_orders credit the email and SMS
messages Privy sent, under the same last-touch rule as the rest of
Privy’s reporting: an order counts when the contact’s most recent
engagement in the 7 days before it was an email open, an email click, or
an SMS click. Orders credited to a display signup are excluded, and
every figure here is dated by when the crediting message was sent,
not by when the order or the engagement happened. A period’s attributed
revenue is therefore the revenue driven by messages sent in that period,
and it includes orders placed after the period closed, whenever the
contact engaged later — so the newest days keep filling in for a while
after the fact. The engagement counts and rates use the same send
window: an open in this period on a message sent last month lands in
last month.
The rates each divide by something different. open_rate is opens
counted once per contact per campaign, over email deliveries — SMS
messages have no opens. click_rate counts clicks the same way but per
channel, over email and SMS deliveries combined. unsubscribe_rate is
unsubscribe and opt-out events, not distinct contacts, over those same
combined deliveries. order_rate is attributed orders over delivered
messages. revenue_per_recipient divides attributed revenue by
email sends only. signup_rate is display form submissions over
display views, so it measures on-site capture, not messaging. signups
counts form submissions on your displays, while new_subscribers counts
contacts becoming subscribed to marketing on either channel from any
source, so the two answer different questions and neither is
de-duplicated by contact.
Periods reaching back before the account’s reporting boundary
(2026-07-01 for most accounts, earlier where more history was
backfilled) are served whole — comparison period included — from
Privy’s historical rollups instead of the live reporting store. The
rate formulas above still hold, but the basis differs: new
subscribers, every by_channel/by_type split, and totals_context are
null; attributed orders and revenue include display-credited orders
and are dated by when the attribution was recorded, not by send time —
so order_rate’s numerator counts orders its message denominator
never sent, and reads a little high for accounts with display-credited
orders; and days are bucketed in US Eastern time regardless of the
account’s time zone. Treat comparisons that straddle the boundary as
approximate, and say so.
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.
{"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/get-report-summary","slug":"/docs/api-reference/get-report-summary","pageMetadata":{"title":"Get business report summary","openapi":"openapi/privy-api.yaml GET /reports/summary","description":"The business-level performance rollup for a period: signups, new\nsubscribers, attributed revenue and orders, engagement rates, and\nbusiness-wide order and revenue totals for context. Pass\n`compare=previous_period` to add previous-period values and typed\nchange deltas to every metric.\n\n`attributed_revenue` and `attributed_orders` credit the email and SMS\nmessages Privy sent, under the same last-touch rule as the rest of\nPrivy's reporting: an order counts when the contact's most recent\nengagement in the 7 days before it was an email open, an email click, or\nan SMS click. Orders credited to a display signup are excluded, and\nevery figure here is dated by when the crediting message was **sent**,\nnot by when the order or the engagement happened. A period's attributed\nrevenue is therefore the revenue driven by messages sent in that period,\nand it includes orders placed after the period closed, whenever the\ncontact engaged later — so the newest days keep filling in for a while\nafter the fact. The engagement counts and rates use the same send\nwindow: an open in this period on a message sent last month lands in\nlast month.\n\nThe rates each divide by something different. `open_rate` is opens\ncounted once per contact per campaign, over email deliveries — SMS\nmessages have no opens. `click_rate` counts clicks the same way but per\nchannel, over email and SMS deliveries combined. `unsubscribe_rate` is\nunsubscribe and opt-out events, not distinct contacts, over those same\ncombined deliveries. `order_rate` is attributed orders over delivered\nmessages. `revenue_per_recipient` divides attributed revenue by\n**email** sends only. `signup_rate` is display form submissions over\ndisplay views, so it measures on-site capture, not messaging. `signups`\ncounts form submissions on your displays, while `new_subscribers` counts\ncontacts becoming subscribed to marketing on either channel from any\nsource, so the two answer different questions and neither is\nde-duplicated by contact.\n\nPeriods reaching back before the account's reporting boundary\n(2026-07-01 for most accounts, earlier where more history was\nbackfilled) are served whole — comparison period included — from\nPrivy's historical rollups instead of the live reporting store. The\nrate formulas above still hold, but the basis differs: new\nsubscribers, every by_channel/by_type split, and `totals_context` are\nnull; attributed orders and revenue include display-credited orders\nand are dated by when the attribution was recorded, not by send time —\nso `order_rate`'s numerator counts orders its message denominator\nnever sent, and reads a little high for accounts with display-credited\norders; and days are bucketed in US Eastern time regardless of the\naccount's time zone. Treat comparisons that straddle the boundary as\napproximate, and say so.\n\n**Required scope:** `reports_read`\n","href":"/docs/api-reference/get-report-summary"},"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: [_jsxs(_components.p, {\n children: [\"The business-level performance rollup for a period: signups, new\\nsubscribers, attributed revenue and orders, engagement rates, and\\nbusiness-wide order and revenue totals for context. Pass\\n\", _jsx(_components.code, {\n children: \"compare=previous_period\"\n }), \" to add previous-period values and typed\\nchange deltas to every metric.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n children: \"attributed_revenue\"\n }), \" and \", _jsx(_components.code, {\n children: \"attributed_orders\"\n }), \" credit the email and SMS\\nmessages Privy sent, under the same last-touch rule as the rest of\\nPrivy’s reporting: an order counts when the contact’s most recent\\nengagement in the 7 days before it was an email open, an email click, or\\nan SMS click. Orders credited to a display signup are excluded, and\\nevery figure here is dated by when the crediting message was \", _jsx(_components.strong, {\n children: \"sent\"\n }), \",\\nnot by when the order or the engagement happened. A period’s attributed\\nrevenue is therefore the revenue driven by messages sent in that period,\\nand it includes orders placed after the period closed, whenever the\\ncontact engaged later — so the newest days keep filling in for a while\\nafter the fact. The engagement counts and rates use the same send\\nwindow: an open in this period on a message sent last month lands in\\nlast month.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The rates each divide by something different. \", _jsx(_components.code, {\n children: \"open_rate\"\n }), \" is opens\\ncounted once per contact per campaign, over email deliveries — SMS\\nmessages have no opens. \", _jsx(_components.code, {\n children: \"click_rate\"\n }), \" counts clicks the same way but per\\nchannel, over email and SMS deliveries combined. \", _jsx(_components.code, {\n children: \"unsubscribe_rate\"\n }), \" is\\nunsubscribe and opt-out events, not distinct contacts, over those same\\ncombined deliveries. \", _jsx(_components.code, {\n children: \"order_rate\"\n }), \" is attributed orders over delivered\\nmessages. \", _jsx(_components.code, {\n children: \"revenue_per_recipient\"\n }), \" divides attributed revenue by\\n\", _jsx(_components.strong, {\n children: \"email\"\n }), \" sends only. \", _jsx(_components.code, {\n children: \"signup_rate\"\n }), \" is display form submissions over\\ndisplay views, so it measures on-site capture, not messaging. \", _jsx(_components.code, {\n children: \"signups\"\n }), \"\\ncounts form submissions on your displays, while \", _jsx(_components.code, {\n children: \"new_subscribers\"\n }), \" counts\\ncontacts becoming subscribed to marketing on either channel from any\\nsource, so the two answer different questions and neither is\\nde-duplicated by contact.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Periods reaching back before the account’s reporting boundary\\n(2026-07-01 for most accounts, earlier where more history was\\nbackfilled) are served whole — comparison period included — from\\nPrivy’s historical rollups instead of the live reporting store. The\\nrate formulas above still hold, but the basis differs: new\\nsubscribers, every by_channel/by_type split, and \", _jsx(_components.code, {\n children: \"totals_context\"\n }), \" are\\nnull; attributed orders and revenue include display-credited orders\\nand are dated by when the attribution was recorded, not by send time —\\nso \", _jsx(_components.code, {\n children: \"order_rate\"\n }), \"’s numerator counts orders its message denominator\\nnever sent, and reads a little high for accounts with display-credited\\norders; and days are bucketed in US Eastern time regardless of the\\naccount’s time zone. Treat comparisons that straddle the boundary as\\napproximate, and say so.\"]\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":"Get business report summary","openapi":"openapi/privy-api.yaml GET /reports/summary","description":"The business-level performance rollup for a period: signups, new\nsubscribers, attributed revenue and orders, engagement rates, and\nbusiness-wide order and revenue totals for context. Pass\n`compare=previous_period` to add previous-period values and typed\nchange deltas to every metric.\n\n`attributed_revenue` and `attributed_orders` credit the email and SMS\nmessages Privy sent, under the same last-touch rule as the rest of\nPrivy's reporting: an order counts when the contact's most recent\nengagement in the 7 days before it was an email open, an email click, or\nan SMS click. Orders credited to a display signup are excluded, and\nevery figure here is dated by when the crediting message was **sent**,\nnot by when the order or the engagement happened. A period's attributed\nrevenue is therefore the revenue driven by messages sent in that period,\nand it includes orders placed after the period closed, whenever the\ncontact engaged later — so the newest days keep filling in for a while\nafter the fact. The engagement counts and rates use the same send\nwindow: an open in this period on a message sent last month lands in\nlast month.\n\nThe rates each divide by something different. `open_rate` is opens\ncounted once per contact per campaign, over email deliveries — SMS\nmessages have no opens. `click_rate` counts clicks the same way but per\nchannel, over email and SMS deliveries combined. `unsubscribe_rate` is\nunsubscribe and opt-out events, not distinct contacts, over those same\ncombined deliveries. `order_rate` is attributed orders over delivered\nmessages. `revenue_per_recipient` divides attributed revenue by\n**email** sends only. `signup_rate` is display form submissions over\ndisplay views, so it measures on-site capture, not messaging. `signups`\ncounts form submissions on your displays, while `new_subscribers` counts\ncontacts becoming subscribed to marketing on either channel from any\nsource, so the two answer different questions and neither is\nde-duplicated by contact.\n\nPeriods reaching back before the account's reporting boundary\n(2026-07-01 for most accounts, earlier where more history was\nbackfilled) are served whole — comparison period included — from\nPrivy's historical rollups instead of the live reporting store. The\nrate formulas above still hold, but the basis differs: new\nsubscribers, every by_channel/by_type split, and `totals_context` are\nnull; attributed orders and revenue include display-credited orders\nand are dated by when the attribution was recorded, not by send time —\nso `order_rate`'s numerator counts orders its message denominator\nnever sent, and reads a little high for accounts with display-credited\norders; and days are bucketed in US Eastern time regardless of the\naccount's time zone. Treat comparisons that straddle the boundary as\napproximate, and say so.\n\n**Required scope:** `reports_read`\n","href":"/docs/api-reference/get-report-summary"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"operationId":"getReportSummary","summary":"Get business report summary","description":"The business-level performance rollup for a period: signups, new\nsubscribers, attributed revenue and orders, engagement rates, and\nbusiness-wide order and revenue totals for context. Pass\n`compare=previous_period` to add previous-period values and typed\nchange deltas to every metric.\n\n`attributed_revenue` and `attributed_orders` credit the email and SMS\nmessages Privy sent, under the same last-touch rule as the rest of\nPrivy's reporting: an order counts when the contact's most recent\nengagement in the 7 days before it was an email open, an email click, or\nan SMS click. Orders credited to a display signup are excluded, and\nevery figure here is dated by when the crediting message was **sent**,\nnot by when the order or the engagement happened. A period's attributed\nrevenue is therefore the revenue driven by messages sent in that period,\nand it includes orders placed after the period closed, whenever the\ncontact engaged later — so the newest days keep filling in for a while\nafter the fact. The engagement counts and rates use the same send\nwindow: an open in this period on a message sent last month lands in\nlast month.\n\nThe rates each divide by something different. `open_rate` is opens\ncounted once per contact per campaign, over email deliveries — SMS\nmessages have no opens. `click_rate` counts clicks the same way but per\nchannel, over email and SMS deliveries combined. `unsubscribe_rate` is\nunsubscribe and opt-out events, not distinct contacts, over those same\ncombined deliveries. `order_rate` is attributed orders over delivered\nmessages. `revenue_per_recipient` divides attributed revenue by\n**email** sends only. `signup_rate` is display form submissions over\ndisplay views, so it measures on-site capture, not messaging. `signups`\ncounts form submissions on your displays, while `new_subscribers` counts\ncontacts becoming subscribed to marketing on either channel from any\nsource, so the two answer different questions and neither is\nde-duplicated by contact.\n\nPeriods reaching back before the account's reporting boundary\n(2026-07-01 for most accounts, earlier where more history was\nbackfilled) are served whole — comparison period included — from\nPrivy's historical rollups instead of the live reporting store. The\nrate formulas above still hold, but the basis differs: new\nsubscribers, every by_channel/by_type split, and `totals_context` are\nnull; attributed orders and revenue include display-credited orders\nand are dated by when the attribution was recorded, not by send time —\nso `order_rate`'s numerator counts orders its message denominator\nnever sent, and reads a little high for accounts with display-credited\norders; and days are bucketed in US Eastern time regardless of the\naccount's time zone. Treat comparisons that straddle the boundary as\napproximate, and say so.\n\n**Required scope:** `reports_read`\n","tags":["Reports"],"security":["134ac571-0840-49f5-bced-8c251de23690"],"parameters":["690630b2-b1d1-47cf-a0d8-b0038d0f4536","d4c5e359-2836-4bba-9197-86b3bd17e784","5582cbf0-2675-46ed-a7a1-a012b08ae1da","1d74c76e-19d1-455b-b567-e6bc8710baa2","32cfb6c7-dcde-4767-8186-ae81079dff5e"],"responses":{"200":"fc2eeefb-2521-4069-a207-6bb0d924631d","401":"ad2e55ea-1b12-4470-9d1b-f3a313b98410","403":"33e7f20a-5860-4442-b11d-3457e6e53ff6","422":"b5908bd5-afac-4232-9fd5-5dc3f76020b2","429":"9a9497f1-349c-4282-b68e-65534ff6ff55"},"method":"get","type":"path","servers":["97f63e03-f020-41b7-a5b9-e312bbfed47d"],"path":"/reports/summary","baseUrlOptions":["https://api.privy.com/v1"],"title":"Get business report summary","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"690630b2-b1d1-47cf-a0d8-b0038d0f4536":{"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"},"d4c5e359-2836-4bba-9197-86b3bd17e784":{"name":"period","in":"query","description":"The date range to report over, resolved in the account's time zone. Pass `custom` together with `start_date` and `end_date`.","schema":{"type":"string","enum":["last_7_days","last_30_days","last_90_days","this_month","last_month","custom"],"default":"last_30_days","description":"The date range to report over, resolved in the account's time zone. Pass `custom` together with `start_date` and `end_date`.","uniqueKey":"","typeLabel":"enum\u003cstring>"},"example":"last_30_days"},"5582cbf0-2675-46ed-a7a1-a012b08ae1da":{"name":"start_date","in":"query","description":"Inclusive start of a `custom` period (ISO 8601 date). Required when `period=custom`, ignored otherwise.","schema":{"type":"string","format":"date","description":"Inclusive start of a `custom` period (ISO 8601 date). Required when `period=custom`, ignored otherwise.","uniqueKey":"","typeLabel":"string\u003cdate>"},"example":"2026-06-01"},"1d74c76e-19d1-455b-b567-e6bc8710baa2":{"name":"end_date","in":"query","description":"Inclusive end of a `custom` period (ISO 8601 date). Required when `period=custom`, ignored otherwise. Custom periods are capped at 366 days.","schema":{"type":"string","format":"date","description":"Inclusive end of a `custom` period (ISO 8601 date). Required when `period=custom`, ignored otherwise. Custom periods are capped at 366 days.","uniqueKey":"","typeLabel":"string\u003cdate>"},"example":"2026-06-30"},"32cfb6c7-dcde-4767-8186-ae81079dff5e":{"name":"compare","in":"query","description":"Pass `previous_period` to include `previous_value`, `change` and `change_type` on every metric and a `comparison_period` block. Any other value is rejected.","schema":{"type":"string","enum":["previous_period"],"description":"Pass `previous_period` to include `previous_value`, `change` and `change_type` on every metric and a `comparison_period` block. Any other value is rejected.","uniqueKey":"","typeLabel":"enum\u003cstring>"},"example":"previous_period"}},"responses":{"fc2eeefb-2521-4069-a207-6bb0d924631d":{"description":"The business's performance rollup over the resolved period.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"period":{"type":"object","description":"The resolved date range the report covers, inclusive, in the account's\ntime zone. Every label except `last_month` ends today, so the last day\nof the range is still in progress: `last_7_days` is the six days before\ntoday plus today, `this_month` runs from the 1st through today, and\n`last_month` is the whole previous calendar month. Custom ranges cannot\nexceed 366 days.\n","properties":{"label":{"type":"string","enum":["last_7_days","last_30_days","last_90_days","this_month","last_month","custom"],"example":"last_30_days","uniqueKey":"data.period.label","typeLabel":"enum\u003cstring>"},"start_date":{"type":"string","format":"date","example":"2026-06-21","uniqueKey":"data.period.start_date","typeLabel":"string\u003cdate>"},"end_date":{"type":"string","format":"date","example":"2026-07-20","uniqueKey":"data.period.end_date","typeLabel":"string\u003cdate>"}},"uniqueKey":"data.period","typeLabel":"object"},"comparison_period":{"oneOf":[{"type":"object","description":"The previous period of the same length, immediately before the report period. Null unless `compare=previous_period`.","properties":{"start_date":{"type":"string","format":"date","example":"2026-05-22","uniqueKey":"data.comparison_period.oneOf.0.start_date","typeLabel":"string\u003cdate>"},"end_date":{"type":"string","format":"date","example":"2026-06-20","uniqueKey":"data.comparison_period.oneOf.0.end_date","typeLabel":"string\u003cdate>"}},"uniqueKey":"data.comparison_period.oneOf.0","typeLabel":"object"},{"type":"null","description":"The previous period of the same length, immediately before the report period. Null unless `compare=previous_period`.","properties":{"start_date":{"type":"string","format":"date","example":"2026-05-22"},"end_date":{"type":"string","format":"date","example":"2026-06-20"}},"uniqueKey":"data.comparison_period.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.comparison_period","typeLabel":"object | null"},"signups":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.signups.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.signups.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.signups.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.signups.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.signups.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.signups.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.signups.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.signups.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.signups.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.signups.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.signups.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.signups.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.signups.unit","typeLabel":"string"},"by_channel":{"oneOf":[{"type":"object","description":"Current-period split by channel, in the parent metric's unit. Null when\nthe period reaches before the account's reporting boundary — the\nhistorical source cannot credit an order to a single message channel;\nnever treat null as zero. Never\ncarries comparison fields, even when the request asked for one — only\nthe parent metric does. On attributed orders and revenue the two legs\nnever double count, because each order is credited to a single message\nand so to a single channel. On signups they can: the split is built\nfrom what each form captured, so a form that took both an email address\nand a phone number counts in both legs, and the legs need not add up to\nthe signup total.\n","properties":{"email":{"type":"number","example":1050,"uniqueKey":"data.signups.by_channel.oneOf.0.email","typeLabel":"number"},"sms":{"type":"number","example":190,"uniqueKey":"data.signups.by_channel.oneOf.0.sms","typeLabel":"number"}},"uniqueKey":"data.signups.by_channel.oneOf.0","typeLabel":"object"},{"type":"null","description":"Current-period split by channel, in the parent metric's unit. Null when\nthe period reaches before the account's reporting boundary — the\nhistorical source cannot credit an order to a single message channel;\nnever treat null as zero. Never\ncarries comparison fields, even when the request asked for one — only\nthe parent metric does. On attributed orders and revenue the two legs\nnever double count, because each order is credited to a single message\nand so to a single channel. On signups they can: the split is built\nfrom what each form captured, so a form that took both an email address\nand a phone number counts in both legs, and the legs need not add up to\nthe signup total.\n","properties":{"email":{"type":"number","example":1050},"sms":{"type":"number","example":190}},"uniqueKey":"data.signups.by_channel.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.signups.by_channel","typeLabel":"object | null"}},"uniqueKey":"data.signups","typeLabel":"object"},"new_subscribers":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.new_subscribers.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.new_subscribers.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.new_subscribers.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.new_subscribers.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.new_subscribers.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.new_subscribers.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.new_subscribers.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.new_subscribers.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.new_subscribers.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.new_subscribers.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.new_subscribers.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.new_subscribers.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.new_subscribers.unit","typeLabel":"string"},"by_source":{"oneOf":[{"type":"object","additionalProperties":{"type":"integer","uniqueKey":"data.new_subscribers.by_source.oneOf.0.additionalProperties","typeLabel":"integer"},"description":"New subscribers grouped by signup source (`display`, `import`,\n`api`, `shopify`, …; `unknown` for unattributed). Current period\nonly. Null means unavailable — the period starts before the\naccount's reporting boundary (2026-07-01 for most accounts,\nearlier where more history was backfilled) or the breakdown\ncould not be computed; an empty object means genuinely zero.\nNever treat null as zero.\n","uniqueKey":"data.new_subscribers.by_source.oneOf.0","typeLabel":"object"},{"type":"null","additionalProperties":{"type":"integer","uniqueKey":"data.new_subscribers.by_source.oneOf.1.additionalProperties","typeLabel":"integer"},"description":"New subscribers grouped by signup source (`display`, `import`,\n`api`, `shopify`, …; `unknown` for unattributed). Current period\nonly. Null means unavailable — the period starts before the\naccount's reporting boundary (2026-07-01 for most accounts,\nearlier where more history was backfilled) or the breakdown\ncould not be computed; an empty object means genuinely zero.\nNever treat null as zero.\n","uniqueKey":"data.new_subscribers.by_source.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.new_subscribers.by_source","typeLabel":"object | null"},"by_channel":{"oneOf":[{"type":"object","additionalProperties":{"type":"integer","uniqueKey":"data.new_subscribers.by_channel.oneOf.0.additionalProperties","typeLabel":"integer"},"description":"New subscribers by channel (`email`, `sms`). Same availability\nsemantics as `by_source`: null means unavailable — never treat\nnull as zero.\n","uniqueKey":"data.new_subscribers.by_channel.oneOf.0","typeLabel":"object"},{"type":"null","additionalProperties":{"type":"integer","uniqueKey":"data.new_subscribers.by_channel.oneOf.1.additionalProperties","typeLabel":"integer"},"description":"New subscribers by channel (`email`, `sms`). Same availability\nsemantics as `by_source`: null means unavailable — never treat\nnull as zero.\n","uniqueKey":"data.new_subscribers.by_channel.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.new_subscribers.by_channel","typeLabel":"object | null"}},"uniqueKey":"data.new_subscribers","typeLabel":"object"},"signup_rate":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.signup_rate.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.signup_rate.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.signup_rate.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.signup_rate.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.signup_rate.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.signup_rate.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.signup_rate.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.signup_rate.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.signup_rate.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.signup_rate.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.signup_rate.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.signup_rate.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.signup_rate.unit","typeLabel":"string"}},"uniqueKey":"data.signup_rate","typeLabel":"object"},"attributed_revenue":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.attributed_revenue.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.attributed_revenue.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_revenue.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.attributed_revenue.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.attributed_revenue.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_revenue.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.attributed_revenue.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.attributed_revenue.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_revenue.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.attributed_revenue.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.attributed_revenue.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_revenue.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.attributed_revenue.unit","typeLabel":"string"},"by_channel":{"oneOf":[{"type":"object","description":"Current-period split by channel, in the parent metric's unit. Null when\nthe period reaches before the account's reporting boundary — the\nhistorical source cannot credit an order to a single message channel;\nnever treat null as zero. Never\ncarries comparison fields, even when the request asked for one — only\nthe parent metric does. On attributed orders and revenue the two legs\nnever double count, because each order is credited to a single message\nand so to a single channel. On signups they can: the split is built\nfrom what each form captured, so a form that took both an email address\nand a phone number counts in both legs, and the legs need not add up to\nthe signup total.\n","properties":{"email":{"type":"number","example":1050,"uniqueKey":"data.attributed_revenue.by_channel.oneOf.0.email","typeLabel":"number"},"sms":{"type":"number","example":190,"uniqueKey":"data.attributed_revenue.by_channel.oneOf.0.sms","typeLabel":"number"}},"uniqueKey":"data.attributed_revenue.by_channel.oneOf.0","typeLabel":"object"},{"type":"null","description":"Current-period split by channel, in the parent metric's unit. Null when\nthe period reaches before the account's reporting boundary — the\nhistorical source cannot credit an order to a single message channel;\nnever treat null as zero. Never\ncarries comparison fields, even when the request asked for one — only\nthe parent metric does. On attributed orders and revenue the two legs\nnever double count, because each order is credited to a single message\nand so to a single channel. On signups they can: the split is built\nfrom what each form captured, so a form that took both an email address\nand a phone number counts in both legs, and the legs need not add up to\nthe signup total.\n","properties":{"email":{"type":"number","example":1050},"sms":{"type":"number","example":190}},"uniqueKey":"data.attributed_revenue.by_channel.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_revenue.by_channel","typeLabel":"object | null"},"by_type":{"oneOf":[{"type":"object","description":"Current-period split by message type, in the parent metric's unit. Null\nwhen the period reaches before the account's reporting boundary — the\nhistorical source does not carry the split; never treat null as zero.\nNever carries comparison fields, even when the request asked for one —\nonly the parent metric does. `campaign` counts newsletters, the one-time\nemail and SMS sends. `flow` is broader than the flows in `/v1/flows`:\nit also covers the account's older automations and the follow-up email\nor SMS a display sends after a signup. The two legs cover every\nattributed message, so they add up to the parent metric's value.\n","properties":{"campaign":{"type":"number","example":190,"uniqueKey":"data.attributed_revenue.by_type.oneOf.0.campaign","typeLabel":"number"},"flow":{"type":"number","example":122,"uniqueKey":"data.attributed_revenue.by_type.oneOf.0.flow","typeLabel":"number"}},"uniqueKey":"data.attributed_revenue.by_type.oneOf.0","typeLabel":"object"},{"type":"null","description":"Current-period split by message type, in the parent metric's unit. Null\nwhen the period reaches before the account's reporting boundary — the\nhistorical source does not carry the split; never treat null as zero.\nNever carries comparison fields, even when the request asked for one —\nonly the parent metric does. `campaign` counts newsletters, the one-time\nemail and SMS sends. `flow` is broader than the flows in `/v1/flows`:\nit also covers the account's older automations and the follow-up email\nor SMS a display sends after a signup. The two legs cover every\nattributed message, so they add up to the parent metric's value.\n","properties":{"campaign":{"type":"number","example":190},"flow":{"type":"number","example":122}},"uniqueKey":"data.attributed_revenue.by_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_revenue.by_type","typeLabel":"object | null"}},"uniqueKey":"data.attributed_revenue","typeLabel":"object"},"attributed_orders":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.attributed_orders.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.attributed_orders.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_orders.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.attributed_orders.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.attributed_orders.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_orders.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.attributed_orders.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.attributed_orders.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_orders.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.attributed_orders.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.attributed_orders.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_orders.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.attributed_orders.unit","typeLabel":"string"},"by_channel":{"oneOf":[{"type":"object","description":"Current-period split by channel, in the parent metric's unit. Null when\nthe period reaches before the account's reporting boundary — the\nhistorical source cannot credit an order to a single message channel;\nnever treat null as zero. Never\ncarries comparison fields, even when the request asked for one — only\nthe parent metric does. On attributed orders and revenue the two legs\nnever double count, because each order is credited to a single message\nand so to a single channel. On signups they can: the split is built\nfrom what each form captured, so a form that took both an email address\nand a phone number counts in both legs, and the legs need not add up to\nthe signup total.\n","properties":{"email":{"type":"number","example":1050,"uniqueKey":"data.attributed_orders.by_channel.oneOf.0.email","typeLabel":"number"},"sms":{"type":"number","example":190,"uniqueKey":"data.attributed_orders.by_channel.oneOf.0.sms","typeLabel":"number"}},"uniqueKey":"data.attributed_orders.by_channel.oneOf.0","typeLabel":"object"},{"type":"null","description":"Current-period split by channel, in the parent metric's unit. Null when\nthe period reaches before the account's reporting boundary — the\nhistorical source cannot credit an order to a single message channel;\nnever treat null as zero. Never\ncarries comparison fields, even when the request asked for one — only\nthe parent metric does. On attributed orders and revenue the two legs\nnever double count, because each order is credited to a single message\nand so to a single channel. On signups they can: the split is built\nfrom what each form captured, so a form that took both an email address\nand a phone number counts in both legs, and the legs need not add up to\nthe signup total.\n","properties":{"email":{"type":"number","example":1050},"sms":{"type":"number","example":190}},"uniqueKey":"data.attributed_orders.by_channel.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_orders.by_channel","typeLabel":"object | null"},"by_type":{"oneOf":[{"type":"object","description":"Current-period split by message type, in the parent metric's unit. Null\nwhen the period reaches before the account's reporting boundary — the\nhistorical source does not carry the split; never treat null as zero.\nNever carries comparison fields, even when the request asked for one —\nonly the parent metric does. `campaign` counts newsletters, the one-time\nemail and SMS sends. `flow` is broader than the flows in `/v1/flows`:\nit also covers the account's older automations and the follow-up email\nor SMS a display sends after a signup. The two legs cover every\nattributed message, so they add up to the parent metric's value.\n","properties":{"campaign":{"type":"number","example":190,"uniqueKey":"data.attributed_orders.by_type.oneOf.0.campaign","typeLabel":"number"},"flow":{"type":"number","example":122,"uniqueKey":"data.attributed_orders.by_type.oneOf.0.flow","typeLabel":"number"}},"uniqueKey":"data.attributed_orders.by_type.oneOf.0","typeLabel":"object"},{"type":"null","description":"Current-period split by message type, in the parent metric's unit. Null\nwhen the period reaches before the account's reporting boundary — the\nhistorical source does not carry the split; never treat null as zero.\nNever carries comparison fields, even when the request asked for one —\nonly the parent metric does. `campaign` counts newsletters, the one-time\nemail and SMS sends. `flow` is broader than the flows in `/v1/flows`:\nit also covers the account's older automations and the follow-up email\nor SMS a display sends after a signup. The two legs cover every\nattributed message, so they add up to the parent metric's value.\n","properties":{"campaign":{"type":"number","example":190},"flow":{"type":"number","example":122}},"uniqueKey":"data.attributed_orders.by_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.attributed_orders.by_type","typeLabel":"object | null"}},"uniqueKey":"data.attributed_orders","typeLabel":"object"},"order_rate":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.order_rate.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.order_rate.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.order_rate.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.order_rate.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.order_rate.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.order_rate.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.order_rate.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.order_rate.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.order_rate.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.order_rate.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.order_rate.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.order_rate.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.order_rate.unit","typeLabel":"string"}},"uniqueKey":"data.order_rate","typeLabel":"object"},"average_order_value":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.average_order_value.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.average_order_value.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.average_order_value.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.average_order_value.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.average_order_value.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.average_order_value.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.average_order_value.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.average_order_value.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.average_order_value.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.average_order_value.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.average_order_value.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.average_order_value.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.average_order_value.unit","typeLabel":"string"}},"uniqueKey":"data.average_order_value","typeLabel":"object"},"revenue_per_recipient":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.revenue_per_recipient.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.revenue_per_recipient.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.revenue_per_recipient.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.revenue_per_recipient.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.revenue_per_recipient.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.revenue_per_recipient.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.revenue_per_recipient.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.revenue_per_recipient.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.revenue_per_recipient.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.revenue_per_recipient.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.revenue_per_recipient.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.revenue_per_recipient.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.revenue_per_recipient.unit","typeLabel":"string"}},"uniqueKey":"data.revenue_per_recipient","typeLabel":"object"},"open_rate":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.open_rate.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.open_rate.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.open_rate.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.open_rate.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.open_rate.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.open_rate.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.open_rate.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.open_rate.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.open_rate.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.open_rate.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.open_rate.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.open_rate.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.open_rate.unit","typeLabel":"string"}},"uniqueKey":"data.open_rate","typeLabel":"object"},"click_rate":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.click_rate.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.click_rate.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.click_rate.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.click_rate.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.click_rate.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.click_rate.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.click_rate.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.click_rate.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.click_rate.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.click_rate.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.click_rate.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.click_rate.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.click_rate.unit","typeLabel":"string"}},"uniqueKey":"data.click_rate","typeLabel":"object"},"unsubscribe_rate":{"type":"object","description":"A report metric with previous-period comparison fields.\n`previous_value`, `change` and `change_type` are null unless the\nrequest passed `compare=previous_period`. `change_type` says how to\nread `change`, and the four values are not interchangeable:\n`relative` is the percent change (one decimal, e.g. 26.5 means\n+26.5%) and is used for count and money metrics whenever the previous\nperiod was non-zero; `percent_point` is the absolute percentage-point\ndelta and is used for every rate metric (never a relative percent, so\na small rate move cannot read as a huge swing); `absolute` is the raw\ndelta in the metric's unit, used when the previous period was zero and\nthis one was not; and `not_comparable` means no delta could be\ncomputed, with `change` null. Units follow the `ReportMetric`\nconventions. A null `value` on a rate metric means the period had no\nvolume to divide by, which is how \"no data\" is distinguished from a\nreal 0% — though not every rate nulls, so a 0 can still mean either.\n","properties":{"value":{"oneOf":[{"type":"number","example":1240,"uniqueKey":"data.unsubscribe_rate.value.oneOf.0","typeLabel":"number"},{"type":"null","example":1240,"uniqueKey":"data.unsubscribe_rate.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.unsubscribe_rate.value","typeLabel":"number | null"},"previous_value":{"oneOf":[{"type":"number","example":980,"uniqueKey":"data.unsubscribe_rate.previous_value.oneOf.0","typeLabel":"number"},{"type":"null","example":980,"uniqueKey":"data.unsubscribe_rate.previous_value.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.unsubscribe_rate.previous_value","typeLabel":"number | null"},"change":{"oneOf":[{"type":"number","example":26.5,"uniqueKey":"data.unsubscribe_rate.change.oneOf.0","typeLabel":"number"},{"type":"null","example":26.5,"uniqueKey":"data.unsubscribe_rate.change.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.unsubscribe_rate.change","typeLabel":"number | null"},"change_type":{"oneOf":[{"type":"string","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.unsubscribe_rate.change_type.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["relative","percent_point","absolute","not_comparable",null],"example":"relative","uniqueKey":"data.unsubscribe_rate.change_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.unsubscribe_rate.change_type","typeLabel":"enum\u003cstring> | null"},"unit":{"type":"string","description":"`count`, `percent`, or a lowercased ISO 4217 currency code.","example":"count","uniqueKey":"data.unsubscribe_rate.unit","typeLabel":"string"}},"uniqueKey":"data.unsubscribe_rate","typeLabel":"object"},"totals_context":{"oneOf":[{"type":"object","description":"Null when the period reaches before the account's reporting boundary; never treat null as zero. Business-wide (not just Privy-attributed) totals over the period, dated by when each order was placed. They are on a different basis from `attributed_revenue`: `total_revenue` is the order total the store charged, tax included, while attributed revenue excludes tax. An attributed share divided out of these will therefore read a little low, and the two are dated differently — treat it as approximate and say so.\n","properties":{"total_orders":{"type":"integer","example":890,"uniqueKey":"data.totals_context.oneOf.0.total_orders","typeLabel":"integer"},"total_revenue":{"type":"number","example":52300,"uniqueKey":"data.totals_context.oneOf.0.total_revenue","typeLabel":"number"}},"uniqueKey":"data.totals_context.oneOf.0","typeLabel":"object"},{"type":"null","description":"Null when the period reaches before the account's reporting boundary; never treat null as zero. Business-wide (not just Privy-attributed) totals over the period, dated by when each order was placed. They are on a different basis from `attributed_revenue`: `total_revenue` is the order total the store charged, tax included, while attributed revenue excludes tax. An attributed share divided out of these will therefore read a little low, and the two are dated differently — treat it as approximate and say so.\n","properties":{"total_orders":{"type":"integer","example":890},"total_revenue":{"type":"number","example":52300}},"uniqueKey":"data.totals_context.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.totals_context","typeLabel":"object | null"}},"uniqueKey":"data","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"data":{"period":{"label":"last_30_days","start_date":"2026-06-21","end_date":"2026-07-20"},"comparison_period":{"start_date":"2026-05-22","end_date":"2026-06-20"},"signups":{"value":1240,"previous_value":980,"change":26.5,"change_type":"relative","unit":"count","by_channel":{"email":1050,"sms":190}},"new_subscribers":{"value":1130,"previous_value":950,"change":18.9,"change_type":"relative","unit":"count","by_source":{"display":980,"import":120,"shopify":30},"by_channel":{"email":1000,"sms":130}},"signup_rate":{"value":3.2,"previous_value":2.9,"change":0.3,"change_type":"percent_point","unit":"percent"},"attributed_revenue":{"value":18450.2,"previous_value":15200,"change":21.4,"change_type":"relative","unit":"usd","by_channel":{"email":15200,"sms":3250.2},"by_type":{"campaign":11400,"flow":7050.2}},"attributed_orders":{"value":312,"previous_value":261,"change":19.5,"change_type":"relative","unit":"count","by_channel":{"email":262,"sms":50},"by_type":{"campaign":190,"flow":122}},"order_rate":{"value":0.6,"previous_value":0.5,"change":0.1,"change_type":"percent_point","unit":"percent"},"average_order_value":{"value":59.13,"previous_value":58.24,"change":1.5,"change_type":"relative","unit":"usd"},"revenue_per_recipient":{"value":0.34,"previous_value":0.3,"change":13.3,"change_type":"relative","unit":"usd"},"open_rate":{"value":41.2,"previous_value":39.8,"change":1.4,"change_type":"percent_point","unit":"percent"},"click_rate":{"value":3.1,"previous_value":2.9,"change":0.2,"change_type":"percent_point","unit":"percent"},"unsubscribe_rate":{"value":0.2,"previous_value":0.2,"change":0,"change_type":"percent_point","unit":"percent"},"totals_context":{"total_orders":890,"total_revenue":52300}}},"examples":{"Example":{"title":"Example","value":{"data":{"period":{"label":"last_30_days","start_date":"2026-06-21","end_date":"2026-07-20"},"comparison_period":{"start_date":"2026-05-22","end_date":"2026-06-20"},"signups":{"value":1240,"previous_value":980,"change":26.5,"change_type":"relative","unit":"count","by_channel":{"email":1050,"sms":190}},"new_subscribers":{"value":1130,"previous_value":950,"change":18.9,"change_type":"relative","unit":"count","by_source":{"display":980,"import":120,"shopify":30},"by_channel":{"email":1000,"sms":130}},"signup_rate":{"value":3.2,"previous_value":2.9,"change":0.3,"change_type":"percent_point","unit":"percent"},"attributed_revenue":{"value":18450.2,"previous_value":15200,"change":21.4,"change_type":"relative","unit":"usd","by_channel":{"email":15200,"sms":3250.2},"by_type":{"campaign":11400,"flow":7050.2}},"attributed_orders":{"value":312,"previous_value":261,"change":19.5,"change_type":"relative","unit":"count","by_channel":{"email":262,"sms":50},"by_type":{"campaign":190,"flow":122}},"order_rate":{"value":0.6,"previous_value":0.5,"change":0.1,"change_type":"percent_point","unit":"percent"},"average_order_value":{"value":59.13,"previous_value":58.24,"change":1.5,"change_type":"relative","unit":"usd"},"revenue_per_recipient":{"value":0.34,"previous_value":0.3,"change":13.3,"change_type":"relative","unit":"usd"},"open_rate":{"value":41.2,"previous_value":39.8,"change":1.4,"change_type":"percent_point","unit":"percent"},"click_rate":{"value":3.1,"previous_value":2.9,"change":0.2,"change_type":"percent_point","unit":"percent"},"unsubscribe_rate":{"value":0.2,"previous_value":0.2,"change":0,"change_type":"percent_point","unit":"percent"},"totals_context":{"total_orders":890,"total_revenue":52300}}}}},"exampleType":"examples"}},"exampleType":"examples"},"ad2e55ea-1b12-4470-9d1b-f3a313b98410":{"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"},"33e7f20a-5860-4442-b11d-3457e6e53ff6":{"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"},"b5908bd5-afac-4232-9fd5-5dc3f76020b2":{"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"},"9a9497f1-349c-4282-b68e-65534ff6ff55":{"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":{"134ac571-0840-49f5-bced-8c251de23690":{"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":"Get business report summary - Privy Knowledge Base","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-22T23:08:30.131Z","originalFileLocation":"docs/api-reference/get-report-summary.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=\"The business-level performance rollup for a period: signups, new subscribers, attributed revenue and orders, engagement rates, and business-wide order and revenue totals for context. Pass compare=previous_period to add previous-period values and typed change deltas to every metric. attributed_revenue and attributed_orders credit the email and SMS messages Privy sent, under the same last-touch rule as the rest of Privy\u0026#x27;s reporting: an order counts when the contact\u0026#x27;s most recent engagement in the 7 days before it was an email open, an email click, or an SMS click. Orders credited to a display signup are excluded, and every figure here is dated by when the crediting message was sent, not by when the order or the engagement happened. A period\u0026#x27;s attributed revenue is therefore the revenue driven by messages sent in that period, and it includes orders placed after the period closed, whenever the contact engaged later — so the newest days keep filling in for a while after the fact. The engagement counts and rates use the same send window: an open in this period on a message sent last month lands in last month. The rates each divide by something different. open_rate is opens counted once per contact per campaign, over email deliveries — SMS messages have no opens. click_rate counts clicks the same way but per channel, over email and SMS deliveries combined. unsubscribe_rate is unsubscribe and opt-out events, not distinct contacts, over those same combined deliveries. order_rate is attributed orders over delivered messages. revenue_per_recipient divides attributed revenue by email sends only. signup_rate is display form submissions over display views, so it measures on-site capture, not messaging. signups counts form submissions on your displays, while new_subscribers counts contacts becoming subscribed to marketing on either channel from any source, so the two answer different questions and neither is de-duplicated by contact. Periods reaching back before the account\u0026#x27;s reporting boundary (2026-07-01 for most accounts, earlier where more history was backfilled) are served whole — comparison period included — from Privy\u0026#x27;s historical rollups instead of the live reporting store. The rate formulas above still hold, but the basis differs: new subscribers, every by_channel/by_type split, and totals_context are null; attributed orders and revenue include display-credited orders and are dated by when the attribution was recorded, not by send time — so order_rate\u0026#x27;s numerator counts orders its message denominator never sent, and reads a little high for accounts with display-credited orders; and days are bucketed in US Eastern time regardless of the account\u0026#x27;s time zone. Treat comparisons that straddle the boundary as approximate, and say so. 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=\"Get business report summary - Privy Knowledge Base\">\u003cmeta data-mint-head property=\"og:description\" content=\"The business-level performance rollup for a period: signups, new subscribers, attributed revenue and orders, engagement rates, and business-wide order and revenue totals for context. Pass compare=previous_period to add previous-period values and typed change deltas to every metric. attributed_revenue and attributed_orders credit the email and SMS messages Privy sent, under the same last-touch rule as the rest of Privy\u0026#x27;s reporting: an order counts when the contact\u0026#x27;s most recent engagement in the 7 days before it was an email open, an email click, or an SMS click. Orders credited to a display signup are excluded, and every figure here is dated by when the crediting message was sent, not by when the order or the engagement happened. A period\u0026#x27;s attributed revenue is therefore the revenue driven by messages sent in that period, and it includes orders placed after the period closed, whenever the contact engaged later — so the newest days keep filling in for a while after the fact. The engagement counts and rates use the same send window: an open in this period on a message sent last month lands in last month. The rates each divide by something different. open_rate is opens counted once per contact per campaign, over email deliveries — SMS messages have no opens. click_rate counts clicks the same way but per channel, over email and SMS deliveries combined. unsubscribe_rate is unsubscribe and opt-out events, not distinct contacts, over those same combined deliveries. order_rate is attributed orders over delivered messages. revenue_per_recipient divides attributed revenue by email sends only. signup_rate is display form submissions over display views, so it measures on-site capture, not messaging. signups counts form submissions on your displays, while new_subscribers counts contacts becoming subscribed to marketing on either channel from any source, so the two answer different questions and neither is de-duplicated by contact. Periods reaching back before the account\u0026#x27;s reporting boundary (2026-07-01 for most accounts, earlier where more history was backfilled) are served whole — comparison period included — from Privy\u0026#x27;s historical rollups instead of the live reporting store. The rate formulas above still hold, but the basis differs: new subscribers, every by_channel/by_type split, and totals_context are null; attributed orders and revenue include display-credited orders and are dated by when the attribution was recorded, not by send time — so order_rate\u0026#x27;s numerator counts orders its message denominator never sent, and reads a little high for accounts with display-credited orders; and days are bucketed in US Eastern time regardless of the account\u0026#x27;s time zone. Treat comparisons that straddle the boundary as approximate, and say so. 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/get-report-summary\">\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=Get+business+report+summary\u0026amp;description=The+business-level+performance+rollup+for+a+period%3A+signups%2C+new%0Asubscribers%2C+attributed+revenue+and+orders%2C+engagement+rates%2C+and%0Abusiness-wide+order+and+reven\u0026amp;theme=a5dbdd3119e247d04186b21c\u0026amp;signature=52d392669e42e1fb89cb34629cf2351a7917af57bbb3b12e463a7988587ef942\">\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=\"Get business report summary - Privy Knowledge Base\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"The business-level performance rollup for a period: signups, new subscribers, attributed revenue and orders, engagement rates, and business-wide order and revenue totals for context. Pass compare=previous_period to add previous-period values and typed change deltas to every metric. attributed_revenue and attributed_orders credit the email and SMS messages Privy sent, under the same last-touch rule as the rest of Privy\u0026#x27;s reporting: an order counts when the contact\u0026#x27;s most recent engagement in the 7 days before it was an email open, an email click, or an SMS click. Orders credited to a display signup are excluded, and every figure here is dated by when the crediting message was sent, not by when the order or the engagement happened. A period\u0026#x27;s attributed revenue is therefore the revenue driven by messages sent in that period, and it includes orders placed after the period closed, whenever the contact engaged later — so the newest days keep filling in for a while after the fact. The engagement counts and rates use the same send window: an open in this period on a message sent last month lands in last month. The rates each divide by something different. open_rate is opens counted once per contact per campaign, over email deliveries — SMS messages have no opens. click_rate counts clicks the same way but per channel, over email and SMS deliveries combined. unsubscribe_rate is unsubscribe and opt-out events, not distinct contacts, over those same combined deliveries. order_rate is attributed orders over delivered messages. revenue_per_recipient divides attributed revenue by email sends only. signup_rate is display form submissions over display views, so it measures on-site capture, not messaging. signups counts form submissions on your displays, while new_subscribers counts contacts becoming subscribed to marketing on either channel from any source, so the two answer different questions and neither is de-duplicated by contact. Periods reaching back before the account\u0026#x27;s reporting boundary (2026-07-01 for most accounts, earlier where more history was backfilled) are served whole — comparison period included — from Privy\u0026#x27;s historical rollups instead of the live reporting store. The rate formulas above still hold, but the basis differs: new subscribers, every by_channel/by_type split, and totals_context are null; attributed orders and revenue include display-credited orders and are dated by when the attribution was recorded, not by send time — so order_rate\u0026#x27;s numerator counts orders its message denominator never sent, and reads a little high for accounts with display-credited orders; and days are bucketed in US Eastern time regardless of the account\u0026#x27;s time zone. Treat comparisons that straddle the boundary as approximate, and say so. Required scope: reports_read\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://privy.mintlify.site/_mintlify/api/og/v2?division=Reports\u0026amp;title=Get+business+report+summary\u0026amp;description=The+business-level+performance+rollup+for+a+period%3A+signups%2C+new%0Asubscribers%2C+attributed+revenue+and+orders%2C+engagement+rates%2C+and%0Abusiness-wide+order+and+reven\u0026amp;theme=a5dbdd3119e247d04186b21c\u0026amp;signature=52d392669e42e1fb89cb34629cf2351a7917af57bbb3b12e463a7988587ef942\">\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/get-report-summary\">\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/get-report-summary.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/get-report-summary#webpage\",\"url\":\"https://help.privy.com/docs/api-reference/get-report-summary\",\"name\":\"Get business report summary\",\"description\":\"The business-level performance rollup for a period: signups, new subscribers, attributed revenue and orders, engagement rates, and business-wide order and revenue totals for context. Pass compare=previous_period to add previous-period values and typed change deltas to every metric. attributed_revenue and attributed_orders credit the email and SMS messages Privy sent, under the same last-touch rule as the rest of Privy's reporting: an order counts when the contact's most recent engagement in the 7 days before it was an email open, an email click, or an SMS click. Orders credited to a display signup are excluded, and every figure here is dated by when the crediting message was sent, not by when the order or the engagement happened. A period's attributed revenue is therefore the revenue driven by messages sent in that period, and it includes orders placed after the period closed, whenever the contact engaged later — so the newest days keep filling in for a while after the fact. The engagement counts and rates use the same send window: an open in this period on a message sent last month lands in last month. The rates each divide by something different. open_rate is opens counted once per contact per campaign, over email deliveries — SMS messages have no opens. click_rate counts clicks the same way but per channel, over email and SMS deliveries combined. unsubscribe_rate is unsubscribe and opt-out events, not distinct contacts, over those same combined deliveries. order_rate is attributed orders over delivered messages. revenue_per_recipient divides attributed revenue by email sends only. signup_rate is display form submissions over display views, so it measures on-site capture, not messaging. signups counts form submissions on your displays, while new_subscribers counts contacts becoming subscribed to marketing on either channel from any source, so the two answer different questions and neither is de-duplicated by contact. Periods reaching back before the account's reporting boundary (2026-07-01 for most accounts, earlier where more history was backfilled) are served whole — comparison period included — from Privy's historical rollups instead of the live reporting store. The rate formulas above still hold, but the basis differs: new subscribers, every by_channel/by_type split, and totals_context are null; attributed orders and revenue include display-credited orders and are dated by when the attribution was recorded, not by send time — so order_rate's numerator counts orders its message denominator never sent, and reads a little high for accounts with display-credited orders; and days are bucketed in US Eastern time regardless of the account's time zone. Treat comparisons that straddle the boundary as approximate, and say so. Required scope: reports_read\",\"dateModified\":\"2026-10-22T23:08:30.131Z\",\"isPartOf\":{\"@id\":\"https://help.privy.com#website\"},\"breadcrumb\":{\"@id\":\"https://help.privy.com/docs/api-reference/get-report-summary#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://help.privy.com/docs/api-reference/get-report-summary#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Privy Knowledge Base\",\"item\":\"https://help.privy.com\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Get business report summary\",\"item\":\"https://help.privy.com/docs/api-reference/get-report-summary\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://help.privy.com/docs/api-reference/get-report-summary#apireference\",\"headline\":\"Get business report summary\",\"name\":\"Get business report summary\",\"description\":\"The business-level performance rollup for a period: signups, new subscribers, attributed revenue and orders, engagement rates, and business-wide order and revenue totals for context. Pass compare=previous_period to add previous-period values and typed change deltas to every metric. attributed_revenue and attributed_orders credit the email and SMS messages Privy sent, under the same last-touch rule as the rest of Privy's reporting: an order counts when the contact's most recent engagement in the 7 days before it was an email open, an email click, or an SMS click. Orders credited to a display signup are excluded, and every figure here is dated by when the crediting message was sent, not by when the order or the engagement happened. A period's attributed revenue is therefore the revenue driven by messages sent in that period, and it includes orders placed after the period closed, whenever the contact engaged later — so the newest days keep filling in for a while after the fact. The engagement counts and rates use the same send window: an open in this period on a message sent last month lands in last month. The rates each divide by something different. open_rate is opens counted once per contact per campaign, over email deliveries — SMS messages have no opens. click_rate counts clicks the same way but per channel, over email and SMS deliveries combined. unsubscribe_rate is unsubscribe and opt-out events, not distinct contacts, over those same combined deliveries. order_rate is attributed orders over delivered messages. revenue_per_recipient divides attributed revenue by email sends only. signup_rate is display form submissions over display views, so it measures on-site capture, not messaging. signups counts form submissions on your displays, while new_subscribers counts contacts becoming subscribed to marketing on either channel from any source, so the two answer different questions and neither is de-duplicated by contact. Periods reaching back before the account's reporting boundary (2026-07-01 for most accounts, earlier where more history was backfilled) are served whole — comparison period included — from Privy's historical rollups instead of the live reporting store. The rate formulas above still hold, but the basis differs: new subscribers, every by_channel/by_type split, and totals_context are null; attributed orders and revenue include display-credited orders and are dated by when the attribution was recorded, not by send time — so order_rate's numerator counts orders its message denominator never sent, and reads a little high for accounts with display-credited orders; and days are bucketed in US Eastern time regardless of the account's time zone. Treat comparisons that straddle the boundary as approximate, and say so. Required scope: reports_read\",\"url\":\"https://help.privy.com/docs/api-reference/get-report-summary\",\"mainEntityOfPage\":{\"@id\":\"https://help.privy.com/docs/api-reference/get-report-summary#webpage\"},\"dateModified\":\"2026-10-22T23:08:30.131Z\",\"publisher\":{\"@id\":\"https://help.privy.com/#organization\"},\"isPartOf\":{\"@id\":\"https://help.privy.com#website\"}}]}\u003c/script>","agentPointerHref":"/docs/api-reference/get-report-summary.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}","description":"Check whether an individual code from a Shopify or BigCommerce pool has\nbeen redeemed, read live from the connected store's per-code usage\ncounter (Privy stores no redemption events).\n\nThis is a counter, not an event log: `usage_count` says how many times\nthe store has accepted the code, but redemption dates, order ids, and\ncustomer attribution are not available — every response repeats this in\nan in-band `note`. Manual pools have no store-side counter and return\n`422 unsupported_coupon_type`.\n\nA spot check for individual codes — there is no bulk sweep; asking\n\"which of my thousands of codes were redeemed\" is not served by this\nendpoint.\n\nMembership semantics: a master pool's single code is matched exactly\n(case-insensitively) before the store is asked. Unique-pool codes are\nresolved against the store directly — Privy stores no per-code linkage\nfor platform pools, so a code from one of your OTHER pools would still\nresolve; the check never crosses accounts.\n\n**Required scope:** `coupons_read`\n","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","description":"Every message campaign **sent in the period**, ranked by attributed\nrevenue, each row carrying the full channel stat block (delivery,\nengagement, unsubscribes, attribution) scoped to the same period — so\nperiod comparisons need no per-campaign detail calls. Zero-revenue\nsends are listed too, ranked after the revenue rows; at most 100\ncampaigns are ranked, and a send with no recorded activity at all in\nthe period does not appear.\n\nBy default the list serves your **newsletters** — email and SMS\none-time sends. Pass `type=flows` to instead rank the **flow\ncampaigns**: the email and SMS messages your automation flows send\n(flow rows carry no `sent_date` or `audience`, and instead name the\nflow that sends them in `flow`, so attributing a message to its flow\nneeds no follow-up request). Use\n`/v1/reports/campaigns/{campaign_id}` for one campaign's\nmost-clicked links or its lifetime funnel.\n\n**Required scope:** `reports_read`\n","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}","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","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":"Get business report summary - 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"]}