takeoffquote

Privacy Policy

Last updated:

TakeoffQuote is built so we can't see your work. Plans, measurements, and prices are processed and stored in your browser — never uploaded to us. There are no accounts. What does exist: cookieless page and product event counts (Cloudflare), scrubbed error reports (Sentry), and — if you buy Pro — payment records held by Paddle plus a hashed license key on our side. Your email is used to send receipts, recover your license key, and answer requests you email us (such as switching plans), nothing else. Emails you send us are kept in our support inbox for 24 months after your request is resolved, in case a refund or payment dispute about them comes up.

What never reaches us

The takeoff loop has no server in it. Your plan PDFs are rendered in the browser and stored in this browser's IndexedDB; your takeoff, quote bindings, and unit prices autosave to IndexedDB and localStorage. Reports and .xlsx quotes are generated in the browser and downloaded straight to your disk. None of it is transmitted to us — we run no upload endpoint for it, so "we don't look at your plans" is an architecture fact, not a promise. The practical side (backups, clearing site data, moving between devices) is covered in the privacy & data doc.

Optional sync you control

The optional shared-folder sync is off by default. When enabled, your project files sync from your browser directly to a folder in your own cloud storage account — one you choose and authorize. That data is governed by your agreement with your storage provider; we don't operate the storage and can't access the folder.

Analytics — no cookies

The website and app use Cloudflare Web Analytics: a cookieless page-view counter that records the page URL, referrer, and browser class. No cookies, no cross-site tracking, no fingerprinting, no advertising identifiers. We see aggregate page counts; we cannot identify you from them.

The app and the website also count nine product events — a plan opened, a quote completed, the Pro gate shown, an upgrade clicked, checkout started, a key activated, a pricing path clicked, interest in a per-project pack, and a click through to the app from one of our pages — so we can tell whether the paywall is working, which way of paying people actually prefer, and which pages bring people to the app. What leaves your browser is the event's name, plus — where one applies — a single word from a fixed list: which price tier it concerned ("monthly" or "yearly"), whether the plan opened was our bundled sample or one of yours ("sample" or "own"), which pricing path was clicked ("subscription" or "per_project"), which pack size drew the interest ("5", "10" or "20"), or which page the click came from — a short name for one of our own pages, such as "home" or "pricing", fixed when the site is built, and "other" for any page not on the list; never the page's address. Nothing else: no cookie, no identifier, and nothing from your drawings — file names, sheet text, measurements and quote totals structurally can't ride along, because the page sends only one of those fixed words and the endpoint receiving it stores only one of those fixed words. Each event is normally counted at most once per browser tab — we count visits, not clicks — and carries no identifier that links it to you or to any other event.

Our payment webhook — the server address Paddle notifies when a subscription changes — adds four counts of its own: a subscription paid for, a subscription canceled, a payment refunded, and a refunded subscription we could not cancel automatically (so we know to cancel it by hand). Each is the event's name plus "monthly" or "yearly", written to the same counter and nothing more: no email, no customer or subscription ID, no amount. Nothing in your browser sends these; the endpoint the app talks to refuses them.

Telling us that a per-project pack interests you is one of those counts and nothing more: the pack size goes, and that is all. There is no form, no email box and no account on that page — we would rather count honest clicks than collect addresses against a launch date we can't promise.

Error reporting — scrubbed

The app reports errors only to Sentry, and events are stripped before they leave your browser: no request payloads, no user object, no breadcrumbs, and error messages are scrubbed of anything file- or path-shaped — a PDF file name never rides along. What ships is the exception type, the scrubbed message, stack frames of our bundled code, and the browser/OS class. Plan content, sheet text, shapes, and quote numbers structurally can't appear in a report.

Payments — what Paddle holds, what we hold

Checkout runs in Paddle's secure checkout. Paddle (paddle.com) acts as merchant of record: you buy from Paddle, and Paddle handles billing, sales tax, and receipts. Your card number goes to Paddle and is never visible to us. Here is the complete list of payment-related data and where it lives:

DataWhere it livesWhy
License key hash (SHA-256 — not the key itself)Our key store (Cloudflare KV)To check that an entered key is valid
Paddle customer & subscription IDsOur key store (Cloudflare KV)To connect subscription events to the key
Plan bought (monthly or yearly)Our key store (Cloudflare KV)To label what your key unlocks
Subscription status & period endOur key store (Cloudflare KV)To know whether Pro is active
Whether the payment was counted, and whether a refund was counted (two yes/no markers per subscription)Our key store (Cloudflare KV)So each is counted once, however often Paddle re-sends it
Your email & billing detailsPaddleReceipts and license key recovery
The license key itselfWith you, and on your Paddle customer recordSo a lost key can be recovered

Your email address is used for Paddle receipts, to recover your license key when you ask, and to act on requests you email us (such as switching between monthly and yearly) — that's it. There is no marketing list, and we never sell or share personal data.

Support email

Email you send to support@takeoffquote.com is received by Cloudflare Email Routing and forwarded to our support inbox, which is the developer's own Gmail (Google) account. We keep your message (and anything you attach) and our reply there to answer your request — switching plans, a refund, recovering a license key — and so we can look the conversation up if a refund or payment dispute about it comes up later. Each conversation is kept for 24 months after your request is resolved, then deleted.

AI and voice features — bring your own

The optional AI assist is dormant until you configure it, and then requests go directly from your browser to the endpoint you chose, with your own API key, under your agreement with that provider — nothing routes through us. Voice input is captured and processed inside your browser; the audio is never stored and never leaves your machine.

Retention and deletion

Your local data is under your control: clearing this site's data in your browser deletes it (export a backup first — we can't restore what we never had). Payment records are kept while your subscription exists and as long as accounting and tax law require. Support emails are kept for 24 months after your request is resolved, as described above. To ask about or delete what we hold, email support@takeoffquote.com.

Your rights

Depending on where you live (GDPR in Europe, CCPA in California, and similar laws elsewhere), you may have rights to access, correct, or delete personal data. Since we hold almost nothing keyed to you personally, such requests usually resolve through the Paddle records and support emails above — email us and we'll sort it out.

Children

TakeoffQuote is a professional estimating tool and is not directed at children under 13.

Changes

Changes to this policy will be posted here with a new "Last updated" date. We won't quietly weaken the local-first architecture this policy describes — it's the product's core promise.

Who we are

TakeoffQuote is operated by Yifeng Jiang (individual). TakeoffQuote operates takeoffquote.com and the TakeoffQuote application. Contact: support@takeoffquote.com.