What Happens to the Photo You Upload
This page traces one photo through the code that runs on the site: what stays in the browser, what is sent to the server, and what the published retention window is. The legal policy is the Privacy Policy; this is the walkthrough.
Checked against the live site’s js/studio.js, t.js and the in-page analytics wrapper on 2026-10-30.
What leaves your device
| You do this | What is sent | Where it goes | What is kept |
|---|---|---|---|
| Open any page | A page-view event: event name, a short label, the page path, the referring host, and campaign tags if the URL has them. No photo. | POST /api/e from the site’s own t.js | Click/page event log on the site’s server; the policy does not state a separate retention period. The photo is not involved. |
| Choose a photo | Nothing. The file is read into the tab with FileReader. | Your browser only | sessionStorage copy only if the data URL is under 1.5 MB; cleared when the tab closes. |
| Style previews (fine-line, blackwork, watercolor, minimal) | Nothing | Canvas in your browser | Nothing |
| Try-on / placement preview | Nothing | Canvas in your browser | Nothing |
| Generate AI line art | The photo as a base64 data URL, plus detail, thickness and your unlock code if one is saved. | POST /api/stencil → the image model named in the privacy policy | Original upload not stored; finished design cached up to 3 days for re-download, then deleted. Automated safety filter first. |
| Download PNG | Nothing | Canvas → your file system | Nothing on the server |
| Get print-ready PDF | The rendered design as a JPEG, the paper size, the physical width in millimetres and your unlock code. | POST /api/stencil.pdf | No separate retention statement in the policy; the PDF is built from the rendered design. |
| Check remaining designs | Your unlock code, as a query parameter: /api/balance?token=… | API | Quota record tied to the code. |
| Checkout | The package id and a channel label. No photo. | POST /api/checkout → Dodo Payments | Order record at the merchant of record. |
“Original upload not stored” and the 3-day cache are the commitments in the Privacy Policy and the homepage FAQ, not something a browser can observe. That is the number to hold the site to.
What stays in your browser
| Where | Key | What it holds | Lifetime |
|---|---|---|---|
| localStorage | pt_token | Your unlock code, so you stay unlocked | Until you clear it |
| localStorage | fq_id | Functional id mirrored from the fq_id cookie; counts the included preview | Cookie 30 days; mirror until cleared |
| localStorage | vt_ch | Channel label returned at checkout | Until you clear it |
| sessionStorage | tf_photo | The last photo as a data URL, only under 1.5 MB | Until the tab closes |
| sessionStorage | vt_attr, ai_ref | Referring site, campaign tags, AI referrer | Until the tab closes |
| Cookie | fq_id | Functional id used to count the included preview | 30 days (per the privacy policy) |
The unlock code is not a password and does not contain your photo. Clearing site data removes it; keep the code somewhere safe if you want to re-download later.
Audit it yourself
- Open the browser’s developer tools, then the Network tab, and filter for stencil.
- Choose a photo and click through the four style previews. No request carries the image — the styles are drawn by canvas code in js/studio.js.
- Click “Generate AI line art”. A POST /api/stencil appears with the image in the JSON body. That is the upload.
- Request the print-ready PDF. A POST /api/stencil.pdf carries the rendered design, not the original file.
If a step does not match what is described here, the code changed. The support address is the right place to ask about it.
Using the site without uploading a photo
The four style previews, the placement try-on and the photo check all run locally. The two actions that need the server are AI line art and the print-ready PDF. If you want zero upload, use the local previews and show the original photo to your artist in person.
Scripts on the page
Every page loads /t.js, a first-party script that records the page view and clicks described above. The site also loads a script from jt-collect.moonhop.workers.dev. It is separate from the first-party code described here; the Privacy Policy’s analytics paragraph — page views, referring site, campaign tags and clicks, no photo — is the description that covers it.
The processors named in the policy are Cloudflare (hosting), fal.ai (image generation and moderation) and Dodo Payments (checkout). The cookies set by this code are the functional fq_id cookie and a test-only _qa cookie.