Fish ("we", "the App") is a Shopify app that provides collection
filtering and search for the merchant's storefront. This policy explains
what data we collect, why, where it is stored, how long we keep it, and how
merchants and shoppers can exercise their rights.
1. Data we collect
1.1 From the merchant (shop owner)
Shop domain, OAuth access token, granted scopes, install timestamp —
required to call the Shopify Admin API on the merchant's behalf.
Billing status — current plan, subscription status, last-checked
timestamp, Shopify shop GID — used to enforce plan limits and show usage
on the "Plan" dashboard tab.
App configuration the merchant sets in the dashboard — search
settings, synonym groups, hidden-product rules, tag exclusions, boost
rules, and (if the merchant opts into semantic search) an API key for a
third-party embedding provider they supply themselves (§1.3).
Product review data, if the merchant uploads a CSV export from their
review platform — review text, rating, and the product it matches to.
We do not collect this from shoppers directly; the merchant supplies it.
1.2 From shoppers (storefront visitors)
We do not collect names, email addresses, physical addresses, or any
other data that directly identifies a shopper.
Search query text and aggregate counts — what shoppers typed into
search, how many times, and whether it returned results — stored per
shop, keyed by the query text itself, not by shopper or session.
Product view counts — how many times each product was shown from
search, a collection or its own page, and for search the normalized query
text that led to it — aggregated per shop, product, source and query, not
by shopper or session.
Filter usage counts — which filter options were opened/selected and
how often, aggregated per shop and filter value (no per-shopper tracking).
Order line items, from Shopify order webhooks, used only to compute
bestseller/trending product rankings — product SKU, name, quantity,
order status. We do not store the buyer's name, email, address, or
payment details.
IP address — used to rate-limit storefront API requests and to reject
forged webhooks. It is recorded in two places:
the web server's access log, on the same line as the requested URL,
the country the request came from and the browser's user agent. For a
search request that URL contains the search text, so while these log
files exist the address and the search sit together. The logs are capped
by size rather than by time — three files of 20 MB — which at current
traffic is roughly 10 hours before older entries are discarded
[measured 2026-08-30]. We do not copy that pairing anywhere else and do
not use it to build a profile of a shopper.
the database, and only for a webhook that fails its signature check.
That is a record about the sender of a forged request, not about a
shopper; those rows are deleted after 7 days.
1.3 Shared with third parties (only if the merchant opts in)
If a merchant enables semantic search and supplies their own API key
for a provider (OpenAI, Voyage AI, Cohere, Jina AI, Google, or
HuggingFace), search query text and product text are sent to that
provider to generate embeddings. This only happens for shops that turn
the feature on and provide a key; it is off by default.
1.4 Service providers that process data for us
To run the App we rely on the following providers. Each receives only what
it needs for its function:
Shopify — the platform the App is built on; we read catalog data and
write product tags and metafields through its Admin API.
Cybercon, Inc. (United States) — hosting of our primary server, which
holds all data described in §1.1 and §1.2.
A hosting provider in France (EU) — the standby server that holds a
daily copy of the database, without Shopify access tokens or webhook secrets.
Cloudflare — network proxy in front of our API. Storefront requests,
including the search text in their URLs, pass through it.
Backblaze B2 (United States) — off-site storage of database backups,
which are encrypted before they leave our server.
Anthropic (Claude API) — analysis of our own operational alert
messages. These contain system status and shop domains, not shopper data.
Google (Gmail) — delivery of those alert messages to our own mailbox.
Cloudflare, Backblaze and Anthropic process data under data processing terms
that include the EU Standard Contractual Clauses for transfers outside the
European Economic Area.
We do not sell any data, and we do not share shopper data with anyone
for advertising or marketing purposes.
2. Where data is stored
PostgreSQL, self-hosted on our own server infrastructure (not a
third-party data warehouse), holds everything in §1.1 and §1.2.
Meilisearch, on the same infrastructure, holds a copy of the
merchant's product/collection/page catalog for search and filtering.
It does not receive shopper data — only catalog content the merchant
already published on their storefront.
Backups. A database dump is taken daily and kept on the same server for
7 days. The copy sent off-site to Backblaze B2 is encrypted before it
leaves the server, with a key the server itself does not hold — so reading
the server does not yield the off-site archive. All copies in that store are
encrypted, including those uploaded before the change.
A standby server holds a daily copy of the database so the storefront
keeps working if the main one fails. Shopify access tokens and webhook
secrets are removed from that copy before it is sent.
Our primary server is hosted in the United States (St. Louis, Missouri)
by Cybercon, Inc. The standby server that holds the daily database copy
described above is hosted in France (Strasbourg, European Union).
Off-site backups are stored with Backblaze B2 in its US-East region and
are deleted 90 days after upload.
3. Retention
Search query logs are deleted automatically once they exceed the
retention window for the merchant's plan (Starter/Pro/Ultimate — the
exact number of days is shown on the "Plan" tab of the app dashboard).
A daily job purges expired rows.
Product view counts are kept for 365 days after a row was last updated,
then purged by a daily job.
Hourly request-volume counters, used only for the traffic charts on
the "Plan" tab, are kept for 40 days and then purged by the same job.
Merchant configuration, billing status, and catalog data are kept for
as long as the app remains installed, per §4.
Order line items — the product, quantity and order number behind our
bestseller and trending rankings — are kept for 180 days. The window is
that long because ranking is computed from a 90-day sales history; shorter
retention would break it. A shopper's rows are also deleted on request ahead
of that, per §4.
Operational records — webhook delivery log 30 days, indexing queue
7 days, sync/job/alert history 90 days — purged by a daily job.
Service logs (web server access log, application log) are capped by size
rather than by time; see §1.2.
Backups are the exception to everything above. Deleting data from the
live database does not reach copies already inside a dated backup, so an
erasure request takes effect in the live system at once and in the backups as
they expire. Local backups expire after 7 days; off-site copies at Backblaze
B2 (region us-east-005) after 90 days. Ninety days is therefore the outer
bound on how long a deleted record can survive anywhere.
4. Deletion on uninstall / merchant request
Uninstalling the app immediately revokes our stored access token, so we
can no longer access the shop's Shopify data.
Within the timeframe Shopify's platform requires, we receive a mandatory
shop/redact webhook and permanently delete all data tied to that shop
domain — configuration, search logs, order-line data, review data,
sync history — and remove the shop's search index.
We do not store a shopper's name, email address or postal address. We do
store order line items linked to a Shopify order number (§1.2), and a
shopper is identifiable through that number. So the two shopper-facing
webhooks are executed, not merely acknowledged:
customers/redact — we delete every order-line row for the orders Shopify
lists in the request, scoped to the shop that sent it.
customers/data_request — we look up what we hold for the orders listed
and provide it to the merchant, who passes it to the shopper. Shopify has
no API to answer this webhook with data, so the export is prepared by hand
within the platform's 30-day window.
5. Your rights
Merchants can request a copy of their stored configuration or ask for
early deletion by contacting us at parsedata633@gmail.com. Shoppers with
questions about a specific store's data practices should contact that
store directly — we act as the store's data processor, not as the data
controller for their storefront.
6. Changes to this policy
We will update the effective date above and, for material changes, notify
merchants through the app dashboard or by email.