Privacy Policy

Last updated: September 2026

Fresh Sheets is a product of Virgo Analytics Ltd, which operates the service and is the data controller for the personal data described in this policy. This policy explains what data Fresh Sheets accesses through your Google account, why, and what happens to it.

Who we are

  • Registered name: Virgo Analytics Ltd
  • Company number: 17397765
  • Registered in England and Wales
  • Registered office: 2 Parkstone Avenue, Poole, BH14 9LR
  • Contact: info@virgo-analytics.co.uk

What Fresh Sheets does

Fresh Sheets is a Google Sheets add-on that reads reporting data from Google Analytics 4, Google Ads, and Google Search Console and writes it into a Google Sheets spreadsheet you choose, on a schedule you set. It does not post to, modify, or delete anything in any of those Google products. Every connector Fresh Sheets ships is read-only, permanently. This is a design decision, not a current limitation.

Google API Services User Data Policy

Fresh Sheets's use and transfer of information received from Google APIs to any other app adheres to the Google API Services User Data Policy, including the Limited Use requirements. In practice, that means: Fresh Sheets only uses the data it accesses to provide the reporting feature you're using it for, does not sell your data, does not use it for advertising, and does not share it with any third party except where necessary to run the service itself (see "Sub-processors" below).

Fresh Sheets does not use any data it receives from Google APIs, including Google Workspace APIs, to develop, improve or train artificial intelligence or machine learning models.

The exact OAuth scopes Fresh Sheets requests, and why

Fresh Sheets asks for eight permissions in total, listed in full below, and never asks for anything beyond them. They are not all requested at once. There are three separate moments, each with its own Google consent screen: when you add Fresh Sheets to a spreadsheet, when you connect your Google account, and when you sign in to your Fresh Sheets account on the web. The first two are set out in the sections below; the third asks only for permissions already listed here.

When you add Fresh Sheets to a spreadsheet

The first time you open the Fresh Sheets sidebar, Google asks you to authorize the add-on itself. Neither of these two permissions can reach any file other than the spreadsheet you are working in, and neither reads your marketing data.

PermissionWhat it accesses
https://www.googleapis.com/auth/spreadsheets.currentonlyOnly the spreadsheet the sidebar is currently open in, and no other file in your Google Drive. Used for four things: identifying which spreadsheet you are in; seeing which tab and cell you have selected, so a new report can be pointed at them; switching you to a report's tab the first time it is written from the sidebar, or when you click to go to it; and showing a one-line message when you first install Fresh Sheets. Fresh Sheets never reads the contents of your cells through this permission.
https://www.googleapis.com/auth/script.container.uiGoogle's platform permission that allows the Fresh Sheets sidebar to appear inside Google Sheets. It grants no access to any of your data.

When you connect your Google account

Connecting is a separate step with its own Google consent screen, which opens in a new browser tab. This is where Fresh Sheets asks for access to your reporting data.

ScopeWhat it accesses
https://www.googleapis.com/auth/drive.fileAccess to the one spreadsheet you choose to connect, granted through Google's own file picker. Fresh Sheets cannot see or access any other file in your Google Drive. What it reads and changes inside that spreadsheet is set out below this table.
https://www.googleapis.com/auth/adwordsAccess to your Google Ads accounts. Google publishes only one permission for its Ads API, and it has no read-only version, so the permission itself would allow changes. Fresh Sheets' access is registered with Google for reporting only, and our code never issues a write: Fresh Sheets reads your reporting data (campaigns, ad groups, ads, keywords and their performance) and never creates, edits, pauses or deletes a campaign, ad, bid or budget.
https://www.googleapis.com/auth/analytics.readonlyRead-only access to your Google Analytics 4 property data.
https://www.googleapis.com/auth/webmasters.readonlyRead-only access to your Search Console data: search queries, pages, clicks, impressions, and position.
openidUsed only to verify your Google account identity when you connect.
emailUsed only to know which Google account you connected, so your saved reports and connection can be associated with you.

What Fresh Sheets does inside the spreadsheet you connect. Each report has a tab of its own: either a new tab Fresh Sheets creates, or an existing tab you point the report at. When you choose an existing tab for a report in the sidebar and Fresh Sheets finds something in it, you are asked to confirm before it is used. On every refresh, everything in a report's tab is replaced with the new figures. Apart from creating a report's tab, nothing else in the spreadsheet is changed. To do this, Fresh Sheets reads:

  • the spreadsheet's title, and the name and size of each tab;
  • when you choose or change a report's tab, the first 200 rows and 26 columns (A1 to Z200) of every tab, only to tell whether a tab already has something in it. Nothing read this way is stored;
  • if a report takes its date range from cells, the values of those cells each time the report runs.

Fresh Sheets never requests broader Google Drive access, such as drive or drive.readonly. It only ever requests drive.file, scoped to the one file you choose to connect.

Signing in to your Fresh Sheets account on the web uses the same openid and email permissions listed above and asks for nothing further.

What Fresh Sheets stores, and what it doesn't

Fresh Sheets stores:

  • Your Google account identity (a stable account identifier and your email address).
  • An encrypted copy of your OAuth refresh token, so Fresh Sheets can access your data on your behalf without asking you to sign in every time. This is encrypted at rest; the encryption key is never stored in the same place as the data it protects.
  • Which permissions Google reports you granted when you connected, and a short-lived access token, also encrypted, kept between refreshes so Fresh Sheets does not have to ask Google for a new one every time. The access token is cleared when you disconnect.
  • The report configurations you build: each report's name, and the fields, date range, filters (including the values you enter in them) and schedule you've chosen for it, and whether a report is paused because your plan runs fewer scheduled reports, with when we told you so.
  • A log of when each report ran and whether it succeeded, for troubleshooting.
  • For each report, the title of the spreadsheet it writes to, the name of its tab, and the name of the Google Analytics property, Google Ads account or Search Console site it reads from, so your reports can be listed and labelled without asking Google each time.
  • A record that lets the sidebar recognise your connection when you reopen it: a one-way fingerprint of the credential kept in your browser, when it was created and last used, and when it expires. It is deleted when you disconnect.
  • For each report, when we last emailed you about it failing, and for your account, when we last told you that you had reached your plan's allowance, and, until it clears, that we told you your scheduled reports could not refresh because Google stopped accepting access to your Google account or a Google usage limit was holding them back, with which connection or Google Analytics property it was about, so the same alert is not sent twice.
  • For your account, when your 30 days of free Plus started and when they end, whether a paid plan has started and ended them, which scheduled report you chose to keep running on the Free plan, and which reminders about the end of your free Plus we have already sent, so none is sent twice.
  • A daily count of how many times you started a report by hand, for the fair use limit on manual refreshes.
  • Once a day, for our own monitoring, a list of the accounts that have reports but no successful refresh in the past week. It holds only each account's internal identifier, a random value Fresh Sheets assigns, and never your email address or anything about your reports. These lists are kept with no end date. Deleting your account removes its identifier from every list already recorded, leaving the day's totals with nothing identifying in them.
  • When an account deletion goes ahead, a record that the deletion ran: the account's internal identifier, when the deletion ran, and the outcome of each step, kept with no end date as a record of whether the deletion was carried out. It holds no email address and nothing about your reports.
  • Your billing records: a reference to your customer record at Stripe, your subscription status, and a record of each billing event Stripe sends us, cut down to identifiers and status. Your name, email address, postal address and card details are not kept in it. Stripe keeps your invoices, so your billing records at Stripe outlive your Fresh Sheets account. After your account is deleted, the billing event records that refer to it are deleted too, each one once it is more than 30 days old; the check runs every day.
  • If you subscribe to a paid plan, which version of our Terms of Service you accepted at checkout, and when.
  • If you joined the waitlist before the product opened: the email address you gave, and the company name and message you chose to add.
  • A cached list of the fields your Google Analytics property offers, so the field picker does not have to ask Google every time you open it. Each Google Analytics property defines its own custom dimensions and metrics, so this list can only come from your property. There is no background job fetching it. The copy is replaced when it is more than a day old and you next open the field picker, so a list you have not opened for a while can be considerably older than a day. If Google cannot be reached at that moment, we keep using the copy we already have rather than showing you an empty picker. One consequence worth knowing: a dimension or metric you have just created in Google Analytics may not appear straight away, and the refresh button in the field picker fetches it immediately. The list holds field names, descriptions and categories as Google supplies them, and none of your figures. It is deleted when you disconnect that Google account. This is set out in more detail on the data deletion page.

Fresh Sheets does not store the marketing data it retrieves from Google Analytics, Google Ads, or Search Console. That data is read from your Google account and written directly into your spreadsheet on each refresh; it isn't kept in Fresh Sheets's own systems afterward.

How your data is protected

All data in transit is encrypted (HTTPS). Your OAuth refresh token is encrypted at rest using a separate encryption key that's never stored alongside the data it protects. Access to production systems and data is limited to the developer.

Where your data is processed

The database is hosted by Neon on Amazon Web Services in the London region (eu-west-2). The application runs on Vercel, and the functions for this project execute in London.

That is not the whole picture, so here is the rest of it. Neon, Vercel, Stripe, Resend and Google are all part of groups headquartered in the United States. United States law can reach a company wherever its servers happen to be, so choosing London infrastructure reduces how far your data travels but does not put it beyond that reach. This is true of nearly every product built the way this one is, and you should be able to weigh it rather than find it out later.

Cookies and tracking

The banner. The first time you visit freshsheets.uk you are asked whether to allow analytics cookies, with Accept and Reject. Nothing is stored until you answer. Your answer is remembered so you are not asked again, and you can change it at any time with the Cookie settings link in the footer.

What is set if you accept.

NameKindSet byExpiresWhat it is for
_gaCookie on .freshsheets.ukGoogle Analytics400 daysA random identifier that lets Google Analytics recognize a returning browser.
_ga_J9KJP3G7DHCookie on .freshsheets.ukGoogle Analytics400 daysSession state for our specific Analytics property.
fs-consentBrowser local storageFresh SheetsUntil you clear itRecords that you accepted, so the banner is not shown again.

What is set if you reject. On the marketing site, no cookies at all. The only thing stored is fs-consent, recording the rejection.

Before you answer. The Google Analytics script loads on every visit, in a mode where all of its storage is switched off by default. So before you touch the banner, one request does reach Google, carrying the address of the page you are on, the page you came from, your browser and device details, and your IP address. It sets no cookie and contains nothing that identifies you; Google uses it only to estimate overall traffic. If you reject, it stays in that mode for the rest of your visit. We would rather say this than let you discover it in a network tab.

Elsewhere in the product. Google Analytics does not run in the Fresh Sheets sidebar or in your account area, and nothing below is used for analytics. These are needed for those parts of Fresh Sheets to work, so they are set whatever you answered on the banner.

NameKindWhereExpiresWhat it is for
__Secure-authjs.session-tokenCookieAccount area30 days after you were last activeKeeps you signed in.
__Host-authjs.csrf-tokenCookieAccount areaWhen you close your browserProtects the sign-in form from requests made by another site.
__Secure-authjs.callback-urlCookieAccount areaWhen you close your browserRemembers which page to return you to after signing in.
__Secure-authjs.pkce.code_verifierCookieAccount area15 minutesA one-time value proving that the sign-in Google returns is the one you started.
fs-credentialBrowser local storageSidebarUntil you clear itLets the sidebar recognise your connection when you reopen it, so you are not asked to connect again each time. It stops working after 180 days without use, or as soon as you disconnect.
fs-handoffBrowser session storageSidebarWhen you close the tabLets the sidebar recover its link to the spreadsheet you are in if the sidebar reloads.
fs-reports-collapsedBrowser local storageSidebarUntil you clear itRemembers whether you collapsed your list of reports.

Sub-processors

These are the companies involved in running Fresh Sheets. Apart from Stripe, for what it collects when you pay (see "Stripe, which sells paid plans" below), none of them is permitted to use your data for their own purposes.

ProviderWhat it doesWhat reaches itWhere it is processed
VercelHosts and runs the applicationEvery request to the site, the sidebar and the account area, and the application's runtime logs, which can include the text of an error and so may quote a tab name or a message returned by GoogleFunctions for this project run in London. Vercel is part of a group headquartered in the United States.
NeonHosts the databaseEverything listed under "What Fresh Sheets stores" aboveAmazon Web Services, London region (eu-west-2). Neon is part of a group headquartered in the United States.
StripeSells you a paid plan as Link (see below), and holds the billing record: the customer record Fresh Sheets creates for you, and the plan you buy or change toYour email address, an identifier for your Fresh Sheets account, your card details, which you enter on Stripe's own form and which we never see or hold, and the billing address you give Stripe, which Fresh Sheets does not storeStripe operates internationally. It is part of a group headquartered in the United States.
ResendSends the emails Fresh Sheets sends you: an alert when a scheduled report fails, a note when it starts working again, a notice when you reach your plan's refresh allowance, two reminders before your free Plus ends, and a note when reports pause because your plan runs fewer scheduled reports, and for your whole account, a notice when your scheduled reports cannot refresh because Google stopped accepting access to your Google account or a Google usage limit is holding them back, and a note when they are refreshing again. It also sends alerts to our own support inboxYour email address; the report's name, the spreadsheet's title and a link to the spreadsheet; when the report failed or recovered, a plain-language description of why it failed, and how many rows it wrote; your plan, its allowance and when it resets, and whether you can still run a report by hand that day; when your free Plus ends and which plan you have chosen to start when it ends, the name and spreadsheet title of the report that keeps running and when it next runs, and the names and spreadsheet titles of the reports that pause; how many of your scheduled reports cannot refresh and how many spreadsheets they are in; the Google Analytics property whose usage limit is holding them back, and since when; and in alerts to our own support inbox: when a Google usage limit holds back Search Console reports, the site's address, your account's internal identifier, a random value Fresh Sheets assigns, and the error text the run stored, and since when; when deleting an account does not complete, that internal identifier and the outcome of each deletion step; and when a billing event from Stripe cannot be applied, the event's identifier and type and the error textEmails are sent from Resend's Ireland region (eu-west-1). That decides where they are sent from, not where they are stored: Resend stores the emails and their delivery logs in the United States, under the EU Standard Contractual Clauses and the UK Addendum in its data processing agreement. Resend is headquartered in the United States.
Google WorkspaceHolds our own mailboxes, including the support inboxAny email you send us, with your email address and anything you include in it; and the alerts Fresh Sheets sends to our support inbox, described in the row above, which can carry your account's internal identifier, a Search Console site's address, the error text a run stored, the outcome of each step of a deletion that did not complete, and a Stripe event's identifier and error textGoogle's own infrastructure. Google is part of a group headquartered in the United States.
Google AnalyticsMeasures use of the public marketing siteThe page address, the referring page, browser and device details, and the IP address of visitors to freshsheets.ukGoogle's own infrastructure. Google is part of a group headquartered in the United States.

Google also appears in this policy in a different role, and the two are worth separating. Google is where your reporting data comes from, not a company we pass it to. Fresh Sheets reads your Google Analytics, Google Ads and Search Console data using the permissions you granted, and writes the results into your own Google spreadsheet. That is your relationship with Google, operating under the permissions listed above. Google Analytics in the table is a separate matter and concerns visitors to our marketing site, not your reporting data. Google has one more role: our mailboxes run on Google Workspace, so any email you send us, including a reply to an email Fresh Sheets sent you, with your email address and anything you include in it, is held by Google.

Stripe, which sells paid plans

Paid plans are sold by Link, part of Stripe, as the seller. Stripe plays two parts, and they are worth separating. For the customer record Fresh Sheets creates for you at Stripe, listed in the table above, Stripe acts for us as a processor. For what you give it when you pay, such as your card details and billing address, Stripe is an independent controller: it uses that data for its own purposes, including tax, fraud prevention, disputes, refunds and your Link account, under Stripe's privacy policy.

Revoking access

You can revoke Fresh Sheets's access to your Google account at any time, in either of two places. On the Connections page in your Fresh Sheets account, choose Disconnect: Fresh Sheets stops using the account straight away and asks Google to revoke the access. Or remove Fresh Sheets at myaccount.google.com/permissions: Google removes the access there, and Fresh Sheets records the connection as ended the next time it asks Google to renew it. Either way your reports stop refreshing. The data deletion page sets out exactly what happens in each case.

How long we keep your data

We keep your account identity, your encrypted refresh token, your report configurations and your run history for as long as your Fresh Sheets account exists. Everything else listed under "What Fresh Sheets stores" is kept for no longer than that, unless a longer period is given beside it. A waitlist entry is kept until you ask us to delete it, or until you delete an account using the same email address, which removes it too. Deleting your account removes everything listed there that belongs to it, within 30 days and usually at once.

Disconnecting your Google account does not delete them. Disconnecting stops Fresh Sheets using your Google account, stops your reports refreshing, and deletes the cached field list described above. Your account, your saved reports and your run history stay until you delete your account, on the Settings page. Deleting is a separate action, and the data deletion page explains the difference.

Your run history records when each report ran and whether it worked. Where a run failed it also holds the error text, and that text can quote the name of a tab in your spreadsheet or a message returned by Google.

Resend, which sends the emails described under "Sub-processors", keeps each email and its delivery log for 30 days. So your email address, and the report name, spreadsheet title and link in an alert, stay at Resend for 30 days after that email is sent. The same applies to the alerts it sends to our own support inbox. Those alerts are also kept in that inbox, which runs on Google Workspace, and deleting your account does not remove them.

The short-lived record that links the sidebar to your browser session stops working ten minutes after it is created. It is deleted the next time anyone connects a spreadsheet, rather than on a timer, so we will not promise a maximum age for it, only that it is useless once expired.

Fresh Sheets never stores the marketing data itself. As described above, it is written directly to your spreadsheet on each refresh and not kept in our systems.

Deleting your data

You can delete your account yourself, on the Settings page in your Fresh Sheets account. You confirm by typing your email address, and everything Fresh Sheets stores about the account, apart from the record that the deletion ran (listed above), is deleted within 30 days and usually at once: your reports and their schedules, your run history, your Google connection and the token it stores, and the account itself. We send you a confirmation email when it is done.

Deleting cancels your subscription immediately. Whether any refund is due is covered by our Terms of Service. Your billing records stay with Stripe.

Data already written into your spreadsheets is untouched. It is yours, in your own files, and Fresh Sheets cannot reach it once the connection is gone.

If you want a copy of your data first, or you would rather we deleted it for you, email support@freshsheets.uk from the email address on your account. We respond within 30 days. See Data deletion for exactly which records this covers, and for the difference between revoking access and deleting stored data.

Changes to this policy

If this policy changes in a way that affects how your data is used, we'll update this page and, where the change is material, make a reasonable effort to notify connected users directly.

Contact

Questions about this policy or how Fresh Sheets handles your data: support@freshsheets.uk.