Accounts, billing and tracking overhaul
Email verification and password reset, account settings, clearer plan limits, stricter and more reliable tracking, and a more accurate view of revenue
- New
Verify your email address. New accounts get a verification link, and the dashboard reminds you until you confirm it.
- New
Forgot password and reset password. Reset links expire after one hour and work once. Accounts that signed up with Google can use the same flow to add a password.
- New
Account settings: change your name, change your password, sign out of all devices, or delete your account together with your websites and all of their data.
- New
Server-side reporting with an ingest secret. Send purchases and events from your own backend and they are recorded as verified revenue. The secret is shown, and can be rotated, on the configure page.
- New
Edit a website's name, domain and time zone, disconnect Stripe, or delete a website. Day boundaries and charts follow the website's time zone.
- New
A new Events page for custom events: top events, counts, unique visitors and trends.
- New
Revenue in more than one currency. Totals are shown in your reporting currency, with other currencies listed separately and every amount in its own currency. Nothing is converted.
- New
Verified and client-reported revenue are shown apart. Stripe and server-side sales are verified, sales reported from a browser are labeled as such, and Stripe test-mode payments are left out of your analytics.
- New
Usage and payment warnings. Your dashboard and billing page warn you at 100% of your tracked events, and a failed payment shows a banner that links straight to updating your card. After a failed payment your account keeps working for 7 days.
- New
Conversion rules support wildcards, such as /thank-you/*. They are evaluated when the pageview arrives, so the tracking script sends one request fewer per page.
- New
Optional data-cookie-domain attribute on the script to keep one visitor across the subdomains of your site.
- Improved
One date range across all dashboard pages, kept in the address and remembered in your browser, with the same colors for the same series in every chart.
- Improved
Stricter passwords, sign-in and sign-up attempt limits, sessions that end when you change your password, and Google sign-in that requires a verified email.
- Improved
Sign-in sessions last at most 90 days from sign-in, and still end after 30 days without use. You sign in again at least every 90 days, and Sign out of all devices ends every session sooner.
- Changed
If someone registered an account with your email address before you could verify it, taking the account over now clears what they could have set up. When you reset the password or sign in with Google for the first time, Stripe is disconnected, conversion rules are removed and the ingest secrets are replaced on its websites. The dashboard shows a dismissible banner with what was removed and what to do next, the sign-in page says so after a password reset, and we send you an email. The websites and everything already recorded are kept.
- Improved
Stripe keys, webhook secrets and ingest secrets are encrypted at rest. The restricted-key link and the docs now list exactly the permissions needed.
- Improved
Terms of service, privacy policy and documentation rewritten, and a new refund policy. Support chat now loads only on public pages.
- Changed
Tracking requests must prove where they come from. Browser requests need an Origin or Referer from your own domain, and calls from your server must send the ingest secret. Unknown website IDs are rejected.
- Changed
Dashboard days follow the website's time zone. They used to follow each viewer's browser time zone, so day totals can differ from what you saw before. Existing websites use UTC until you choose a time zone under Configure, Website details, and new websites start with the time zone of the browser that added them.
- Improved
The tracking script sends its requests without cookies and with an origin-only referrer. If you serve the script through your own domain, the recommended proxy setup now also removes the Cookie and Authorization headers before forwarding. The Next.js guide has a middleware version, and nginx and Cloudflare Worker versions of it.
- Changed
Conversion rules match the whole page path. They used to match any address that contained the rule text, so a rule such as checkout also matched /checkout/complete. Use /checkout* or /checkout/* for that. Letter case, query strings, fragments and trailing slashes are ignored.
- Changed
Plan limits are enforced and each customer gets one free trial. Up to 120% of your tracked-event limit nothing is dropped. Beyond it, custom events and conversions sent from browsers are not recorded until the next billing period. Stripe revenue, events from your server and pageviews are never dropped for being over the limit.
- Changed
A purchase event that includes an amount counts as two tracked events, because it is recorded as a custom event and as a sale. An event without an amount counts as one.
- Changed
Raw pageview, custom event and conversion event records are deleted after 25 months. Revenue is kept.
- Changed
Custom events, sales and conversions reported from a visitor's browser also have a daily allowance for each IP address and website: 10% of your plan's event limit, at least 100 and at most 2,500 per UTC day. Events from your server with the ingest secret and Stripe revenue are not limited by it.
- Changed
Requests for website IDs we have not looked up recently, including made-up ones, are limited to 120 per minute for each IP address. Known websites are not affected.
- Changed
Currency codes must be real ISO 4217 codes. Made-up codes such as ZZZ are rejected with invalid_request instead of getting their own line in your reports.
- Changed
A conversion rule that only differs by a query string or a #/route, such as /#/thank-you or /?order=done, can no longer be saved, and one saved earlier is disabled instead of matching your home page. Use a path rule, or send the conversion from your app.
- Improved
When your server reports a sale with the ingest secret that the browser already reported (same order ID), the sale is upgraded to verified in place and takes the server's amount, currency, email and product.
- Fixed
A sale that Stripe reports is now counted once when your page or your server also reported it with the Stripe Checkout Session ID (cs_...) or PaymentIntent ID (pi_...) as the order ID. Stripe's record replaces the reported one, whichever arrives first, and the usage it counted is given back. A different order ID, such as your own order number, cannot be matched to Stripe's record and still counts twice.
- Fixed
A purchase or conversion reported with a Stripe test Checkout Session ID (cs_test_...) as the order ID is treated as test data: it is left out of your analytics and not counted toward your plan usage, and the answer says testMode: true. The purchase event itself is still stored and counted. A PaymentIntent ID (pi_...) looks the same in test and live mode, so it cannot be detected.
- Fixed
A sale is credited to the source the visitor most recently arrived with in the 30 days before it. A visit that has no source of its own, reported as direct, no longer replaces a real source, so with data-cookie-domain a visitor who lands from Google on www and buys on app.example.com is credited to Google.
- Fixed
$0 checkouts, such as free trials and 100% coupons, are no longer recorded as revenue.
- Fixed
The first payment after a free trial is counted as a new order, so trial funnels show their conversions, and refunds issued before a sale reached us are picked up when the sale is recorded.
- Fixed
When several websites share one Stripe account, the first payment and the renewals after a free trial are now tied to the website that sold them, and cancellations are recorded per website. For subscriptions and free trials, also set subscription_data.metadata with websiteId, as the docs show.
- Fixed
The in-product purchase snippet for sites with Stripe connected now uses the Stripe Checkout Session ID as the order ID, so the sale from Stripe replaces the browser's report instead of counting twice.
- Fixed
A sale amount must be a plain number in currency units. A formatted string such as "1,500.00" stores the event but records no sale, and the response now says so with revenue: "ignored" and revenueReason: "invalid_amount". The size limit for a sale sent from a browser is scaled up for currencies with a small unit, such as JPY, KRW and IDR, and a report with the ingest secret is only bounded by 1e12.
- Fixed
Sites on shared hosting domains, such as vercel.app and github.io, are treated per project and not per platform, so a visit from one project to another is no longer counted as internal navigation.
- Fixed
Sign-in redirect fragments, such as #access_token=..., are never collected. A hash route that contains = or &, or that is longer than 100 characters, is dropped and only the origin and path are stored.