Hangsight privacy policy
Photoreal is an optional Pro feature and is disabled by default at launch. While it is off, no photo or crop is sent to Google Gemini or any other AI service.
Who we are and contact
Hangsight helps Shopify merchants show artwork on a shopper's wall.
Operator: Ayman F Almatrudi, an individual freelance developer trading as Nafud Apps, the developer name shown on Shopify. Postal address: Building 4030, Muhammad Ibn Mehmood Al Kilani St, Al Narjis Dist., Riyadh 13333 (short address RAJD4030), Kingdom of Saudi Arabia.
Privacy questions and requests: privacy@hangsight.com. General support: support@hangsight.com.
Merchant data we hold
We hold Shopify sessions and access/refresh tokens, including merchant staff fields Shopify supplies (which may include names and email addresses); shop domain and ID, plan and subscription status, development-store flag, language and installation timestamps. These support authentication and operation of the app.
We hold settings, size mappings, product overrides (artwork selection, crop, dimensions, fit and exclusions), size coverage results, daily aggregate counts, the billing/usage ledger and quota reservations. Merchant lifecycle analytics record setup and usage milestones; review-prompt state records eligibility and whether a prompt was shown. Billing records contain amounts, usage, idempotency keys and provider acknowledgements, not photos or prompts.
Compliance audit records contain the request topic, time and a customer hash. Temporary request identifiers are cleared when a request is fulfilled. Minimal webhook receipts prevent duplicate processing. Hash-keyed quota counters and trial history prevent quota and trial resets on reinstall.
Shopper photos
Photos are processed on-device by default. The standard preview renders on the shopper's device and never uploads the photo for rendering. Avoid photos containing people or private documents.
If the browser cannot decode a HEIC photo, a notice explains server conversion before any upload. Continue sends it to our server; Cancel returns to photo selection without uploading. HEIC conversion runs in memory only in an isolated, short-lived decoder process; the photo is not stored on disk or in the database, and the process releases its memory on completion or timeout. The returned JPEG has metadata removed.
When optional Pro photoreal is available, it requires consent. The crop around the artwork goes to our server and to Google Gemini (paid API); the server combines it with the product artwork. Input crops are removed when the job ends. Outputs expire within 24 hours, or 10 minutes after first read, whichever comes first; Delete now requests immediate removal. Photoreal remains off by default. Before any input crop is written to disk, the server reconstructs it from sRGB pixels, removing EXIF (including GPS), XMP and embedded color profiles.
Google does not use paid API inputs or outputs to train its models and keeps them for a limited time for abuse checks. Google states no fixed retention period in the cited terms. Source: Gemini API Additional Terms of Service, dated 2026-04-28, as recorded in the product specification.
Photos never touch the SQLite storage volume. Photoreal files use the ephemeral app filesystem (/tmp/photoreal by default in production), outside the volume and its snapshots; production configuration rejects photo storage inside the database directory. A machine replacement can remove these transient files before their normal expiry.
The SQLite volume has daily Fly.io snapshots kept for 5 days (FACT; Fly volume snapshots). These snapshots contain the merchant records listed above: sessions/tokens, shop and subscription records, settings/mappings/overrides, analytics, billing and quota ledgers, compliance/webhook receipts, trial history and review state. The database also contains photoreal job metadata (shop/product IDs, status, timestamps, usage/cost and file paths), but no photo bytes. Live database deletion does not immediately erase older snapshots; those expire under the snapshot retention policy.
No accounts, cookies or tracking
We create no shopper accounts and set no cookies for the wall preview. We do not use advertising tracking or cross-site shopper profiles. Shopify and the merchant's other services have their own policies. A random modal-session ID is used in memory for duplicate suppression, never saved in our database. If the merchant enables cart tagging, Shopify receives a private cart attribute containing up to 20 previewed variant IDs; it contains no photo or shopper identifier.
Storefront analytics
We store aggregate daily counts per shop and product, such as preview opens, completions and add-to-cart actions. These counts contain no shopper identifiers; no IP addresses or user agents are stored in the app database or app logs.
For rate limiting, a trusted X-Forwarded-For entry is selected from the right using the configured proxy depth, then hashed with HMAC-SHA256 using the analytics salt (or app secret when the salt is unset). The salted hash stays in memory in endpoint/shop and cross-shop buckets; unavailable trusted entries use shop limits only. Buckets expire after their configured window (up to 24 hours) and are pruned on subsequent requests. Preview-completion duplicate suppression lasts 10 minutes. Process restart clears this memory. Per-shop limits are enforced; IP-derived limits are advisory only until the proxy depth is verified and TRUSTED_PROXY_HOPS_VERIFIED=true: would-be denials are logged without IP values or hashes and do not block requests. A time-boxed diagnostic, enabled only while DIAG_UNTIL is in the future, records only X-Forwarded-For entry counts and X-Wallviz header presence under fixed test labels, never IP values, IP hashes or header values. Hosting and Shopify network processing are separate from app database storage.
On-device room memory
Remembering a room is opt-in. IndexedDB stores a JPEG copy (at most 1024 pixels on its long edge) and calibration in this browser for up to 7 days of reuse. Other scripts on the store (the theme and other apps) can read site storage. Expired rooms are deleted when the storefront loader next runs, even without opening the modal, or on the next app read; a closed browser may retain the bytes longer. The Forget this room button removes it immediately. Clearing the site's browser storage also removes it. Uninstalling the merchant app cannot erase a shopper's browser storage.
Processors
- Fly.io hosts the app, in-memory HEIC conversion, ephemeral photoreal files and the database storage volume. Region:
ams(Amsterdam, Netherlands). Fly.io may process request metadata, such as IP addresses, in its own network and platform logs under its own terms; the app does not store that metadata in its database. - Google processes images through the paid Gemini API only when photoreal is available and requested with consent. Production configuration requires Gemini whenever photoreal is enabled; HEIC conversion does not use an AI processor.
- Shopify provides the shop platform, app authentication, billing and storefront proxy.
Retention
| Data | Retention and deletion |
|---|---|
| Standard preview | On-device only; no server photo storage. |
| HEIC fallback | Request processing in memory only; no persistent copy. |
| Photoreal input | Removed at job end; 24-hour expiry is the cleanup backstop. |
| Photoreal output | Expires at the earlier of creation + 24 hours or first read + 10 minutes; Delete now removes it on request when available. |
| Photoreal job rows and orphan files | Sweeper runs every 10 minutes; rows and files older than 24 hours are removed at its next run. Physical cleanup can therefore lag expiry by up to 10 minutes while the service runs. |
| Remembered room | Opt-in IndexedDB; 7 days of reuse, expiry removal on next storefront load or read, or Forget. |
| Sessions and tokens | Deleted on uninstall or shop redaction. |
| Settings, mappings, overrides, daily counts, billing ledger, review state | Kept while installed; removed on shop redaction. |
| Compliance audits | 30-day cutoff, purged after compliance processing and at runtime initialization; idle processes need an external cleanup schedule. |
| Merchant lifecycle analytics | Shop identity is pseudonymized on redaction; no automatic age-based purge is configured. |
| Hash-keyed quotas, trial ledger and webhook receipts | Retained after redaction for abuse prevention and retry protection; no automatic expiry is configured. |
| Database volume snapshots | Daily Fly.io snapshots kept for 5 days; these are the only backups and contain no photo bytes. |
Deletion requests
Merchants can email privacy@hangsight.com or uninstall through Shopify. Uninstall immediately deletes sessions. Shopify sends shop/redact about 48 hours later; processing it deletes shop settings, mappings, overrides, daily counts, billing records, review state and all tracked photoreal files and jobs. It does not delete the retained hash-keyed quota/trial records, pseudonymized lifecycle analytics or minimal webhook receipts described above. We therefore do not claim that uninstall deletes every record.
We hold no Shopify customer data for this product. customers/data_request returns no customer records; customers/redact has no product customer records to delete. Compliance requests are authenticated and acknowledged, with minimal audit records. Requests about orders or a store account should go to the merchant.
Protected customer data
Version 1 accesses none of Shopify's protected customer data. The proxy's logged_in_customer_id is ignored and never stored. The app requests exactly read_products to read artwork images, variants and sizes; read_themes to detect whether the app block is on the product template; and write_app_proxy to serve the storefront preview endpoints. Order attribution is not available; accessing orders would require a separate permissions review and policy update.
Children
The app is not directed at children and does not create age profiles. Please avoid including children or other people in room photos. Email privacy@hangsight.com about any photo or data concern.
Changes
We update this policy when processing changes and revise the date above. The policy linked in the app describes the current service; new photo processing requires the applicable notice and consent.