Legal
What Liftable reads, stores and deletes.
Written from what the app actually does. Every claim below corresponds to something in the code, and the deletion behaviour is what Shopify's own privacy webhooks trigger.
Last updated 17 September 2026
Who we are
Liftable is a Shopify app that watches a merchant's store, prices what each conversion problem costs, drafts a change for the merchant to approve, and helps the merchant measure the result.
We are the data controller for the account information of the merchant who installs the app, and a data processor for the store data we read on their behalf. Write to privacy@liftable.dev about anything on this page.
What installing Liftable asks Shopify for
Install asks for nine permissions. Six only read. Three can write, and each is for one thing:
- Read orders (read_orders) — to attribute revenue to a test, to size a test before it starts, and to report the store's own order totals back to the merchant.
- Read products (read_products) — to crawl the storefront, to model pricing, and to read the unit costs the store keeps for its products, so an order's margin can be worked out.
- Read themes (read_themes) — to fingerprint the theme and to draft a change without applying it.
- Read shipping (read_shipping) — to check free-shipping thresholds and the shipping step of checkout.
- Read discounts (read_discounts) — to check which discount codes are live.
- Write pixels (write_pixels) — to register Liftable's checkout pixel with Shopify when the store is connected.
- Read customer events (read_customer_events) — so that checkout pixel receives Shopify's checkout events.
- Write delivery customizations (write_delivery_customizations) — to run a shipping-threshold test through a Shopify Function, and only once the merchant has approved that test.
- Write discounts (write_discounts) — to run an automatic-discount test through a Shopify Function, and only once the merchant has approved that test.
What install does not ask for
Install does not ask for permission to write to a theme, to shipping settings, or to checkout. Without theme write permission Liftable cannot build a theme test at all: the test stops and says why. Only the merchant can grant that permission, on Shopify's own consent screen; Liftable does not ask for it on its own. Theme changes are made on a duplicate theme, never by editing the live theme in place.
What we keep from an order
When a store connects we read its last 60 days of orders, and after that Shopify tells us about each new order, each change to one, and each refund. From each order we keep: the order id, the time, the order total, the tax, the shipping total, the currency, the discount codes used, the amounts refunded, the cost of the goods (from the unit costs the store keeps in Shopify, or estimated from the store's gross margin), and a scrambled fingerprint of which product variants and quantities it contained, used only to tell whether a later change to the order changed the goods. Where our storefront pixel ran with the shopper's consent, we also keep the test arm it put on the cart and the Liftable visitor and session id it put there with it. We do not keep the customer's name, email, phone number or address, or a readable list of the items in the order.
The checkout pixel reads the checkout total, the order id, the checkout token (used as the session id for that checkout), which checkout step was reached, and the test arm on the cart.
We use these to attribute revenue to each side of a test, to mark the storefront session an order came from as one that ordered, to check a store has enough orders before a test starts, to watch a running test's guardrails, including its margin, to spot unusual swings in orders, and to show the merchant their own totals, refunds, margin and average order value.
What we store
Per store: the connection tokens, an aggregate profile (sessions, average order value, margin), the order records and pixel data described on this page, the problems found and their evidence, experiments and their results, decisions and their reasons, the merchant's own rules, conversations with the agent, and an audit log of everything the app did.
Order records are kept in a form that supports attribution — the identifiers needed to tell whether an order came from a test's control or its variant. We do not build shopper profiles, and we do not use any store's data to benchmark or train against another's, apart from the anonymised test effect sizes described under "The one thing combined across stores".
Access tokens and connector credentials are encrypted at rest with a key held outside the database.
Shopper consent
The storefront pixel asks Shopify's Customer Privacy API before it does anything. Until Shopify says analytics is allowed for that shopper — for example, after they accept it on the store's cookie banner, where one is required — the pixel sets no cookie, stores nothing in the browser, sends nothing to us and puts nothing on the cart. A shopper who never consents is not put in a test and sees the store as it is.
If a shopper withdraws consent, the pixel stops collecting and sending on that page, removes the cookies it set in that browser, including the one recording which side of a test they are on, and removes the test information it put on their cart. The page they withdraw on may still show the version of the store they were already seeing; from the next page, they see the store as it is. An order already placed keeps the test side it was placed under.
The checkout pixel runs inside Shopify's customer privacy settings: it declares that it needs analytics consent, and Shopify only runs it when that consent allows.
How long we keep it
A job runs every day and deletes, one store at a time, anything older than these periods:
- Storefront pixel data — pages viewed, clicks, scroll depth, form field names (never what was typed), and the visitor and session ids that link them: 90 days.
- Order attribution records — order id, time, totals, tax, refunds, cost of goods, currency, discount codes, which side of a test the order was on, and the visitor and session id where the order carries them: 25 months, so a receipt can compare a month with the same month a year earlier. At the same age, the order id is removed from the audit log.
- Storefront scans — the scan record, its report, and the screenshots and page copies taken during the scan: 12 months.
One store cannot see another
Every query is scoped to a single store by the database itself, not only by our code: each table carries the store it belongs to, row-level security policies enforce it, and the application connects as a role that cannot bypass those policies. The one thing combined across stores is described next, and it holds no store's data.
The one thing combined across stores
When a test judged on conversion rate or revenue per visitor finishes, its effect size — the relative change it made, such as +3%, and how certain that is — is combined with the effect sizes of finished tests of the same kind on other stores, grouped by the check the test fixed, the store's category and the measure it was judged on. A combined figure is kept only when at least five different stores and ten tests contributed to it, no one store counts for more than 30% of it, and it is rounded to the nearest half percentage point. It holds nothing else: no revenue, orders, sessions, conversion rates, shopper data, store names or identifiers.
It is used for one thing: the starting assumption of the next test of that kind, so the test is sized and read against how big the effects of that kind of change have really been on other stores, and the effect it expects is a realistic one. It is never shown as another store's result.
The combined figures are rebuilt every night, so a store's tests stop counting towards them at the next rebuild after it opts out or is deleted, and a figure that has not been rebuilt for two days is not used. The setting is for each store: to opt a store out, an owner of that store opens Settings → Stores in Liftable and turns off "Use and share anonymised test results". One switch covers both directions: from that moment the store's new tests no longer start from the combined figures, and its own results leave them at the next rebuild. A test already running keeps the starting assumption it began with. If you can no longer open the store in Liftable, write to privacy@liftable.dev and we will opt it out.
Other systems, where a merchant connects them
A merchant may connect Klaviyo, GA4, Meta Ads, Google Ads, PostHog, BigQuery, Stripe, Gorgias, Recharge, Judge.me, Marketo or Slack. We read only what the connector's documented scopes allow, we do not write to any of them without an approved experiment, and disconnecting one stops the reads immediately.
From PostHog, BigQuery and Marketo we keep only counts per landing page or per email — no shopper or lead identifiers. From Stripe we keep only counts and rates of payments, refunds and subscriptions — no amounts, customer details or card data, and we accept only a restricted key limited to reading charges and subscriptions.
Who else processes this data
These services process data for us, each for one job:
- Vercel — hosting, and file storage for scan screenshots and reports (Vercel Blob). Where we configure an S3-compatible bucket instead, scan files are stored there.
- Neon — the Postgres database.
- Anthropic — the AI model behind the agent. It reads the store's own data to answer the merchant's questions and draft proposals. Order data reaches it only as totals for the store — order count, revenue, average order value, and projections built from them — never as individual order records. Store data sent to the model is not used to train it.
- Sentry — error reports from the app, with default personal data collection turned off.
- Clerk — merchant sign-in.
- Stripe — card billing for merchants who pay by card. It holds the merchant's billing details, never shopper data.
- Resend — transactional email, such as a scan report someone asked for or a merchant's monthly receipt.
- Slack — only where a merchant connects it, to post decisions and results into their workspace.
If a merchant connects their own AI assistant
A merchant can connect an AI assistant of their own choosing to Liftable, using a key they create. It can use the same tools as Liftable's agent, limited to what that key allows: it sees the same store data, including order totals, and nothing from any other store. Which assistant that is, and where it sends what it reads, is the merchant's choice.
Shopper data, and deleting it
We answer Shopify's three mandatory privacy webhooks:
- A shopper data request records which order records we hold for that customer, with a 30-day deadline, and is answered through the merchant.
- A customer redaction deletes our records of the orders named in the request, any refunds we hold for them, and the storefront pixel session each of those orders came from: its pages viewed, clicks and other events.
- A shop redaction deletes the store's data, including the screenshots and page copies from its scans. What remains: a record that the store existed and was deleted; the audit log, with every entry's details replaced by a note that they were redacted; and, if the merchant paid us by card, our billing record with the store link removed.
Uninstalling
Uninstalling revokes our access immediately and purges the store's access token. Shopify then sends a shop redaction, which removes the store's data as described above. A merchant who wants their data removed sooner can write to us and we will do it on request.
Rights
A merchant, or a shopper acting through a merchant, can ask what we hold, ask for a copy, ask for a correction, or ask for deletion. Write to privacy@liftable.dev. We answer within 30 days.
Changes
When this page changes materially we will say so on it and date it. The date at the top is the date of the current version.