Sortia for Google Sheets, privacy policy, last updated September 27, 2026

Your spreadsheet data never leaves your sheet.

Two permissions, and no cell value, label or formula is ever sent. Everything that does leave is printed on this page, field by field.

Free readings never reach a model Two OAuth scopes Sortia asks for No Drive access Counting tokens deleted after 30 days

What is never sent.

Cell values, in any form.

Column headers and row labels.

Sheet names and file names.

Formulas.

Anything you did not type into the box yourself.

A written reading is checked against that list in your browser. A reply carrying a figure we did not send is discarded, and the built-in sentence is shown instead.

What does leave, and when

  • Anonymous feature-usage events, including which of our example templates you loaded. No spreadsheet data, no email, no account identifier, no license key.
  • License checks, in the two weeks before a key expires, and once more when an organization key is activated.
  • For a Pro user who asks for a written reading, the shape of that one result: ratios, correlations and cell references.
  • Published result links, only when you press Publish; the list of your links, only when you press Show my shared links in Settings; each carrying a fixed hashed id of your install and nothing else.

Read the written-readings payload, field by field

The short version

Your spreadsheet data never leaves your sheet. All computation (statistics, machine learning, simulations, optimizers, matching, forecasting) runs inside Google's Apps Script environment and your browser. The add-on never transmits your cell values, formulas, labels or sheet names. What it does send is set out in full below: anonymous feature-usage events, which carry no spreadsheet data and no account identifier; if you buy a license, the license checks that go with activating and renewing your key; and, only if you hold a Pro license and ask for a written reading of a result, the shape of that result (ratios, correlations and cell references, no values), which you can inspect before and after it is sent and which your administrator can switch off entirely.

What the add-on can access

The add-on requests two narrow permissions:

PermissionWhy
View and manage spreadsheets that this application is installed in (spreadsheets.currentonly)Read the ranges you point a tool at and write result sheets back. It cannot see any other file in your Drive.
Display sidebars and dialogs (script.container.ui)Show the tool panels.

Google attaches two more to every Workspace Marketplace install, your primary Google account email address and your basic profile information, so the consent screen and the listing's Permissions tab show four rather than two. Sortia does not use either of them. Its own code asks Google who you are and gets nothing back, which is why activating an organization key has to ask the holder to type an address at the covered domain instead of reading one.

What that list allows is one thing; what it cannot allow is the more useful half, and it is arithmetic on the manifest rather than a promise. What an add-on can see works through it, along with the one thing a short permission list still cannot tell you.

What we collect

Almost nothing, and never your data. Specifically:

  • Your spreadsheet data never leaves your sheet. No cell values, ranges, formulas, labels, sheet names or file information are ever read by us or sent anywhere. The one thing derived from a result that can leave, for a Pro user who asks for it, is the shape of that result, listed field by field in the section on written readings below.
  • Anonymous feature-usage events. The add-on sends a short event to our server at these moments: when the sidebar opens (boot and session), the first time it ever opens for you (first_open), when a tool panel opens (view), when a run finishes and writes a result, or fails, or a panel fails to load or has to be reset after an error (run, mounterr), when a run fails, and when the sidebar recovers from an unexpected error, a second event naming the kind of failure with one word from our own fixed list (bridge_stale, sheets_timeout, formula, rolled_back, partial, too_big, refused, auth_refused, stale_sheet, no_access, service, script or unknown), never the error message itself (err). When that word is refused it means the run was stopped by one of Sortia's own guards because the request could not be carried out as asked, and the sidebar showed you a sentence saying how to fix it; with that word the event may carry one more word from a second fixed list saying what kind of problem the guard found (range_empty, range_small, non_numeric, header, too_many, output_big, stale_window, param, plan, degenerate or other), for example that the selected range was empty or that a header row was selected as data; it records the kind of problem and the tool, never the range you selected, never what you entered and never the sentence you were shown. auth_refused means Google refused a request from a sidebar that was already open, which can happen when several Google accounts are signed in to one browser, and stale_sheet means the sidebar was still open after its spreadsheet was closed or replaced. no_access means Google reported that you can open the spreadsheet but not change it, or that Sortia was installed without permission to read spreadsheets; it records that word only, never which spreadsheet or who shared it. service means Google's own Sheets or Apps Script service reported a failure, and script means Sortia's own code threw an error; both are chosen by matching the failure's wording against a fixed list of Google's own phrasings and JavaScript error names; the wording itself is never sent. When a panel fails to load, the event may also name which step failed with one word (render, restore, chart, wire or other). The add-on also sends, after a successful run, which of five coarse duration ranges it fell into, such as under four seconds, never a precise time (perf), the first time a run ever finishes for you (first_run), and when you reach one of the five Pro engines without a license or click an upgrade button (gate), and when a reading of a result or a tool suggestion is shown (assist, carrying only which of the three surfaces it was and whether the built-in text or a written reading was used), and when you load one of our example templates from the template library (template, carrying only the short name we gave that example, such as loanpayoff, so we can tell which examples people actually start from), and a small set of outcome signals (ux), each one word from a fixed list: the first-result card's button was pressed or the card was closed (reveal_cta, reveal_dismiss), a result stayed on screen for three seconds (result_seen), you pressed thumbs up or thumbs down under "Was this useful?" (react_up, react_down), a result was exported, copied or written to the sheet (result_export), you pressed the button to try a tool on our sample data or to load an example (sample_run, example_load), the same kind of refusal happened twice in a row (refuse_repeat), the very same refusal happened twice in a row, counted from a hash kept in your browser and never from the message or the cell it names (refuse_same),a run was stopped before it started because a required input was missing (preflight_block), a Risk run was started with a goal on an output, counted once and never with the goal itself (goal_set), and the help card for a Google authorization refusal was shown or its Retry button was pressed (auth_card, auth_retry), that the help card was shown after a request had already succeeded in the same sidebar session, or that a request succeeded again after the help card was shown (auth_card_late, auth_recovered), counts only, and, for the experimental live estimate cells feature that is off unless you turn it on in Settings, that Settings was opened (exp_settings_viewed), that the feature was turned on or off (exp_livecells_enabled, exp_livecells_disabled), that the template workbook link was pressed (exp_template_copied), how you answered the one-tap poll about whether the odds moved (exp_poll_yes, exp_poll_no), and that the Diagnose check found an odds formula showing a number (exp_odds_recomputed); the check reads the formulas on the active sheet to find EST and ODDS cells and whether each shows a number or an error; only counts and yes/no answers come back to the sidebar, and none of the formulas, cells or values leave your sheet. For the experimental guided builder, also off unless you turn it on in Settings: that the flow was opened (exp_builder_opened), that it reached a working model (exp_builder_completed), whether it matched one of our templates or drafted a model from your answers (exp_builder_matched_template, exp_builder_drafted_spec), and that a draft was rejected by our checker once (exp_validator_rejection), a count only; your answers and the draft never leave your browser except into your own sheet. For published result links: that the preview was opened, that a link was published, and that a link was revoked (share_preview, share_publish, share_revoke); what a link contains is described under published result links below, and none of it travels on this counting wire. Four more moments, each a count of a press or of something appearing on screen: Verify pressed on a result's receipt (receipt_verify), the receipt copied as JSON (receipt_copy), an estimate edited after a "What matters most" line was shown, counted once and never with the value (driver_edit), the guided builder's plan box appearing with a plan in it (exp_builder_plan_seen), and the hub search answering a question about the product itself, counted once and never with the question (hub_orient). For the experimental Guide, off unless you turn it on in Settings: that a message was sent, that a suggested model was opened, and that a drafted shape was handed to the guided builder (guide_turn, guide_suggest_open, guide_draft_open), counts only; the words never travel with them. A reaction is a count of up or down per tool and never text: there is no text box, and the "Tell us what went wrong" link that follows a thumbs down opens a draft in your own mail program, which you can send or discard. So that the question is not asked more than once a week per tool, your browser keeps the date it was last shown, and a new account that has seen the first example screen keeps a note of which example that was. Both stay in your browser and are never sent. Each event contains only the kind, the tool or engine name from a short fixed list published in our repository (docs/ANALYTICS.md), the action where relevant, the name of the example template when you loaded one, the failure word, the kind-of-problem word, the step word, the outcome word or the duration range where the event is one of those just described, a plain date label, one rotating counting token, described in the next bullet, and a random identifier for the message itself, made up fresh for each message and unrelated to you, your account or your file, which exists only so that a message the sidebar had to send again after a network failure can be told apart from a new one and counted once. The event sent when the sidebar opens also carries the short build identifier of the add-on version that is running, a stamp our own build tools wrote into the code, so we can tell whether an update has actually reached people; it says which version of our code you have and nothing about you or your file. Nothing else is attached: no spreadsheet data, no cell values, ranges or sheet names, nothing you typed, no email or account identifier, and no license key. Every one of those names, the template names, failure words, kind-of-problem words and outcome words included, is a word we chose and published; the build stamp identifies our code and nothing about you; none of them is anything you wrote, and none of them describes your file. As with any web request it arrives with an IP address attached; our code neither reads nor records it, though Google Cloud's own request logs hold it under Google's retention. When a message does not match the fixed vocabulary on this page, our server refuses to store it and keeps only a daily count of how many messages it refused, split by which of our own fixed reasons applied, for example that the tool name was one this server does not recognize, or that the duration range was. Those reasons are words our code chose about its own decision; nothing from a refused message is kept.
  • The counting token, and exactly what it can and cannot tell us. So that we can tell one busy user from ten quiet ones, the add-on stores one random number in your account's add-on storage. It is generated on your device, it is not your email, your account id, or anything derived from you or your files, and it never appears on a sheet you can see. We never receive that number. What we receive is a one-way token derived from it that changes every day. So two events you send on the same day can be recognized as coming from one person, which is how we tell reach from repetition, and your three spreadsheets count as one user rather than three. Two events sent on different days cannot be connected to each other at all, by us or by anyone reading our data. No request ever carries more than that single day token. So that we can also count weekly and monthly activity without ever putting two different tokens in one message, the add-on additionally sends a separate one-field message, at most once a week and once a month, containing only a weekly or monthly token and nothing else, at a randomly chosen moment. Before August 28, 2026 the number was stored per spreadsheet and the counts meant files rather than people; our own dashboards label the change. One honest residual: your messages reach us from your IP address, and Google Cloud's request logs hold caller IPs under Google's retention; the random timing and once-per-period sending make that a weak correlation, not a join we or anyone could perform from our data. One exception, added 2026-09-26: the published-links feature sends a separate, non-rotating hash of the same stored number, so that a link you publish one day can be listed and revoked the next. It is sent only on publish, on revoke and when you ask Settings to show your links; it is never sent with a usage event, and our server cannot turn it back into the daily token or vice versa.
  • Clicking an upgrade button opens our pricing page in a new tab, with the name of the limit you met and, if you had loaded one of the example templates, the name of that template in the address bar, so the page can show you the right plan. The address also carries a fresh random id minted for that click, which lets us count how many checkouts start and how many finish. That id is random: it is not the counting token, is not derived from it or from anything about you or your file, and cannot be connected to the anonymous usage counts above. You can see the whole address in your browser, and it carries nothing else.
  • License checks. Your license key is verified inside the add-on, by checking its signature locally, so day-to-day use of a key involves no network call. Three things do reach our server, and each of the three carries the key. One. When your key is inside the last two weeks before it expires, or has already expired, the add-on sends the key to us to collect its replacement, so a renewal does not interrupt you. That one happens on a personal key as much as on any other. Two. If your key is an organization-wide site or school license, activating it sends the key and the work email address you type on the activation screen, so we can check the address belongs to the organization that bought the license and count how many people are using one key. Our server turns that address into a keyed hash and keeps only the hash and a running count on the purchase record; the address itself is not stored. Three. On an organization-wide site or school license, and only there, the add-on sends the key on its own to ask whether the administrator has turned the AI reading on. It is sent once per sidebar session, at the first moment a reading would be requested. Because that request is how the answer is found, it goes out before the answer is known, so it is sent on a seat where the feature turns out to be off just as it is on a seat where it is on. It carries the key and nothing else, and our server stores nothing from it. None of the three carries any spreadsheet data. The second and third are not sent for a personal key.
  • No Google account information is read or stored by us. The add-on asks for no email or profile permission, so it cannot read the address of the Google account it is running under, and it never asks our server who you are. On a personal paid plan the license key you paste does carry the email address you bought it with, which is how a plan is confirmed without an account system; that address came from you at checkout, never from your Google account or your file. On a site or school license the key carries the organization’s domain instead of any one person’s address, which the written-readings section below sets out.
  • Saved settings (risk-input distributions, scenarios) are stored inside your own spreadsheet on hidden sheets; they travel with the file and stay under your control.
  • Purchases happen on our website via Stripe, not inside the add-on; Stripe's own privacy policy governs payment details. We receive your email and expiry to mint your license key.
  • Published result links, only when you press Publish. The add-on can publish one result as a read-only page at sortia.io/r/. Nothing is published until you have seen a preview listing exactly what the page will contain and pressed Publish. A published page holds the verdict sentence, the odds, the "what matters most" line, the run receipt (trial count, sampler, seed, two hashes, version numbers and the run time), an optional title you type, and, only if you leave them switched on, your inputs as low-to-high ranges. It never holds cell values, formulas, other tabs, the file name, or anything about your Google account. Our server stores that page and a record of it under a hashed copy of the add-on's random owner id, never an email; it counts how many links you publish per day and per month, and it records nothing when someone reads the page. Links expire after one year and you can remove one sooner from the add-on. On an organization key the add-on also asks our server once per session whether your organization allows publishing, sending the organization's domain from the key and nothing else.

The usage events, the three license-check requests above, the written-readings payload in the next section and the four published-link requests (publish, revoke, the list you ask for in Settings, and one organization check) are everything the add-on sends. If we add anything to that list, this page is updated in the same release that adds it, and the date at the top moves.

Written readings, and the AI reading (Pro)

After a run (a simulation, a schedule, a decision, a project plan or an optimization), Sortia shows a plain sentence about what the result says. For everyone, that sentence is written by the add-on itself from the figures the engine computed, in your browser, with nothing sent anywhere. A Pro user can additionally have a short AI reading written by a language model (Google's Gemini API, called from our server under our paid account). This is opt-in by plan: no free user is ever sent to a model, and a Pro user can turn it off for themselves from the Sortia home screen. Organization-wide site and school licenses are off by default and stay off until the administrator turns the feature on at sortia.io/activate. With the reading off, nothing derived from a result of yours is sent anywhere and no model is called. A free user and a Pro user who has switched it off for themselves make no request at all. On an organization-wide seat one request is still made, and it is the third license check described above: the key on its own, asking the administrator’s setting, which is how the off is found in the first place.

When it is on, the exact payload is this, and nothing else. You can see it under "See what was sent" beneath any written reading.

FieldWhat it isExample
touchWhich surface asked: explain (a result reading), route (a tool suggestion), build (a described model)explain
keyYour license key, so our server can confirm the plan is Pro before doing anything. A key is base64 of the email address the license was bought under and its expiry date, then a signature, so that address is readable from the key; on a site or school license the encoded address is the organization's domain rather than a person. Not derived from anything in your sheet, and not forwarded to the model.
payload.kindThe kind of result, from a fixed listsimulation
payload.trialsHow many trials the run used10000
payload.outputs[].refThe output cell's reference, which means nothing outside your sheetD10
payload.outputs[].p10r, p90r, meanr, p80rThe P10, P90, mean or P80 divided by the median: ratios, so the magnitude of your figures is not recoverable0.72
payload.drivers[].refAn input cell's referenceB3
payload.drivers[].rhoThat input's rank correlation with the output, between -1 and 1-0.71
payload.shapeFor a Decisions, Project Planning or Optimize reading only, in place of trials, outputs and drivers: a short fixed list of ratios, shares, counts and yes/no flags per kind. Decision tree: gapr, breakeven. Weighted scoring: margin, deciderShare. Multi-criteria: margin, flips. Game: equilibria, dominantP1, dominantP2, firstMover, dealBeatsDefault. Critical path: criticalShare, slackr. Critical chain: bufferUsed, fever. Resource load: over, clashes, unassigned. Risk register: topShare, mitigation, savesr, payback. Earned value: spi, cpi, tcpi, eacr. S-curve: lastr, remainr, bufferr, readings. Optimize: improvement, cells, maximise. No option, task, owner, criterion or risk name and no absolute figure is among them.{"gapr":0.18,"breakeven":1}
payload.questionFor a tool suggestion or a described model only: the sentence you deliberately typed into that box
payload.candidatesFor a tool suggestion or a described model only: the short list of tool or template ids the model may choose from["schedule","cpm"]

Never sent: cell values in any form, column headers, row labels, sheet names, file names, formulas, or any text you did not type into the box on that surface. The model returns prose with placeholders; the real figures and labels are put back in by your browser, and a reply that contains a figure we did not send is discarded in favour of the built-in sentence. Our server keeps no copy of the payload or the reply beyond Google Cloud's request logs under Google's retention; it records only a daily count of how many readings were written. No spreadsheet content is used to train any model: the Gemini API is used under Google's paid terms, which exclude training on submitted data, and nothing derived from your cells is submitted in any case.

The Guide (experimental, Pro, off until you turn it on in Settings). A chat box under the search on the Sortia home screen, for two questions: what Sortia can do for your situation, and what shape a model for it should have. Typing to it is the opt-in, and the box says this before your first message: What you type here, the list of Sortia's ready-made models, and any result you attach are sent to Google's Gemini API, from our server under our paid account, to answer you. Nothing from your spreadsheet is included: not a number, not a label, not a tab name. That is the whole payload: the words you typed in that box, the names and one-line descriptions of our ready-made models, and, only if you attach one, a result you already chose to publish as a link (its title, verdict, odds lines and receipt, as described under published result links below). The reply is a short answer, up to three of our model names, and at most a structure for a model, with names and no numbers; you type every figure yourself in the guided builder, and the Guide never writes to your sheet. Our server counts the messages per account per day and keeps no copy of them beyond Google Cloud's request logs under Google's retention. Your spreadsheet data never leaves your sheet through this box either.

Data processing details

  • Tool inputs (the cell ranges you select) are processed in-memory during a run and written back as output sheets in the same spreadsheet.
  • Saved risk inputs and scenarios are written to a hidden sheet inside your own file. Nothing on that sheet leaves your spreadsheet.
  • Templates you load are written to clearly named sheets (Template …) in your spreadsheet and are yours to delete.
  • Error logs, if any, go to Google's own Apps Script logging (Stackdriver). You can see them for your account, and failures in the add-on's code are also logged to Sortia's own Google Cloud project, where the developer can see the error text. Our error messages are written in our own words and may name a cell reference or a count; they never contain cell values, labels, sheet names, formulas or text typed into your sheet. When a run fails for a reason Sortia cannot name (the failure words unknown, service and script), the first few words of the error sentence travel with the count, with every number, quoted text and cell address removed first, and are kept only in Sortia's own Google Cloud logs, never in the daily counts.

How your data is protected

  • The strongest protection is not holding it. Sortia operates no database of user content. Your spreadsheet data is never copied to us, so there is no store of it to breach, subpoena, or leak.
  • Computation stays where your data already is. Analysis runs in your browser and in Google’s Apps Script environment, inside the spreadsheet you opened Sortia in. Access is limited by the spreadsheets.currentonly scope, so the add-on cannot reach any other file in your Drive even if it tried.
  • Everything that does leave is encrypted in transit. The only network requests Sortia makes are the anonymous usage events, the license checks and the written-readings payload described above, and all of them use HTTPS with TLS.
  • Secrets are held in Google Secret Manager, not in code or configuration files. The license signing key and the model API key are never exposed to the add-on or the browser.
  • Access is limited to the developer (Ben Malott) through a Google account protected by two-step verification. No third party, contractor, or subprocessor has access to Sortia’s infrastructure.
  • Payments are handled entirely by Stripe. Sortia never sees or stores card details.

Data retention and deletion

  • Google user data: retained for zero days. Sortia does not store your spreadsheet content, your Google account details, or anything derived from them, at any point. There is nothing to delete because nothing is kept.
  • What lives in your own spreadsheet stays yours. Result tabs, example sheets, and the hidden settings sheet (saved distributions and scenarios) are written into your file. Delete those sheets, or the file, and the data is gone. The random counting number described above is not on a sheet and is not in the file at all: it lives in your Google account's add-on storage, alongside three small bookkeeping markers (whether your first open has been reported, whether your first finished run has been reported, and which week and month were last counted). All of them are invisible in the grid, none of them is ever sent to us, and because they belong to your account rather than to any one file, deleting a spreadsheet does not remove them; removing Sortia from your Google account is what does. Before August 28, 2026 these were stored in each file and did go with it. Uninstalling the add-on removes our access immediately.
  • Counting tokens are kept for 30 days, in a Google Cloud database in the United States, and are then deleted automatically. After that, all that remains is daily totals: how many accounts were active, how many runs finished, how many times each plan limit was met. Those totals are plain numbers with no token in them and we keep them indefinitely. Any daily total we publish that covers fewer than five accounts is suppressed rather than shown, so a small number can never point at one person.
  • Purchase records are held by Stripe under their retention policy, because tax and accounting law requires keeping invoices. We keep your email address only for as long as your subscription is active, solely to issue license keys.
  • To delete your counting data, remove Sortia from your Google account. The random id lives in that account's add-on storage, which only Sortia can read, and once the add-on is gone no future token can be derived from it. Deleting a spreadsheet does not remove it, because since August 28, 2026 the number belongs to your account rather than to any one file. Tokens already sent are not linked to you or to your Google account, so there is nothing to look up by name; they are deleted automatically within 30 days. For purchase records, which are held by Stripe and do carry your email address, email privacy@sortia.io and we will remove what we hold within 30 days and confirm when it is done.

Who is responsible for your data

Sortia is built and operated by Ben Malott, a sole developer based in California, USA, who is the data controller for the limited information described above. For any question about this policy, or to exercise the rights below, email privacy@sortia.io.

Two services process information on our behalf: Google Cloud hosts the license and usage endpoints, and Stripe processes payments. There are no other subprocessors, and no contractors or third parties have access.

Why we are allowed to process it

  • To provide what you bought. Your email address is used to issue and refresh license keys. This is necessary to perform our contract with you.
  • To keep the product working and improve it. Anonymous usage counts tell us which plan limits people meet and which upgrade prompts get clicked. This is our legitimate interest in maintaining and improving Sortia, and it is designed so it cannot identify you.
  • To meet legal obligations. Stripe retains invoices because tax and accounting law requires it.

Your rights

Wherever you live, you may ask us to give you a copy of any information we hold about you, correct it, delete it, restrict or object to how we use it, or provide it in a portable form. Email privacy@sortia.io and we will respond within 30 days at no charge. In practice these requests are simple to satisfy, because the only things we hold that could identify you are an email address tied to an active subscription and, on a site license, the keyed hash of the work address the holder typed at activation.

If you are in the EU, the UK, or Switzerland, you also have the right to complain to your national data protection authority. If you are in California, we confirm that Sortia does not sell or share personal information, and never has.

Where your data is processed

Your spreadsheet content stays in Google’s systems in your own account and is never sent to us. The small amount of information we do handle, license checks and anonymous usage counts, is processed on Google Cloud servers in the United States. If you are outside the United States, that means this limited information crosses a border, and we rely on the standard contractual clauses that Google Cloud and Stripe maintain for such transfers.

Cookies and children

The Sortia website uses Google Analytics to understand which pages people visit, which sets Google Analytics cookies in your browser. We use it for aggregate page statistics only: no advertising trackers, no cross-site tracking, and nothing from your spreadsheets ever reaches it. The add-on sets no cookies and sends nothing to Google Analytics.

Sortia is not directed at children and we do not knowingly collect information from anyone under 13. If you believe a child has provided information, email us and we will delete it.

Limited use of Google user data

Sortia’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. Sortia does not transfer Google user data to third parties, does not use it for advertising, and does not allow humans to read it.

Changes and contact

Material changes to this policy will be reflected in the add-on listing and this document with an updated date. For questions about this policy or your data, email privacy@sortia.io.

Now put a client file in it.

You have read what leaves. Two permissions, computed where your data already is, and the whole payload above.

Estimates in, odds out.

Home· Start here· Templates· Pricing· Teams· Tell someone· Privacy· Terms· Developers· Support· Changelog· Validation· Performance· © 2026 Sortia · Made for Google Sheets™. Google Sheets™ and Google Workspace™ are trademarks of Google LLC.
Google Sheets™ is a trademark of Google LLC. Sortia is not affiliated with or endorsed by Google.