Privacy Policy
Last updated: October 29, 2026
FinalFrame is an AI-powered photography critique service built for photographers. We know photographers care deeply about how their images are handled, so this policy is written in plain language. It explains exactly what data we collect, why, where it goes, and how you can control it.
1. Who We Are
FinalFrame is operated by Crypto Brains DOO, a company registered in Serbia. For any privacy-related questions, you can reach us at:
- Company: Crypto Brains DOO
- Registration: Serbian Business Registers Agency (APR), company registration number (matični broj) 21754757
- Address: Jove Kursule 9, Šabac 15000, Serbia
- Email: support@finalframe.photo
- Website: https://finalframe.photo
For the purposes of the EU General Data Protection Regulation (GDPR), Crypto Brains DOO acts as the data controller for the personal data described in this policy.
2. Data We Collect
2.1 Account Data
When you create an account, we collect and store:
- Email address: provided through our authentication provider (Supabase Auth)
- Full name: if provided by your identity provider or entered by you
- Display name and username: if you set them for your public profile. If you sign in with Google, we use the name on your Google account as your display name until you change it in your account settings
- Avatar image: if you upload one
- Bio: if you choose to write one for your public profile
- Language preference
- Preferred photo editor: used to generate editor-specific editing guidance
- Account creation date
2.2 Photographs and Image Data
When you upload a photograph for critique, we process the following data:
- Your uploaded file: held in our secure cloud storage only while the critique is produced, then deleted. We do not keep the original file you uploaded.
- A processed copy: images are re-encoded through the Sharp image library. This process strips GPS coordinates and other sensitive EXIF metadata from the stored copy. The stored version is converted to JPEG and may be resized if larger than 4,096 pixels on either edge.
- A separate AI-analysis copy: a resized version sent to the AI model for critique. This copy is also stripped of GPS data.
- Computed image metrics: we compute a tonal histogram, sharpness measurement, color cast detection, and dominant color palette from your image. These metrics supplement the AI's visual analysis, are included in the critique prompt, and are stored as text with the critique record for as long as that critique exists.
2.3 EXIF Metadata We Extract and Retain
We extract a limited set of photographic and editing metadata from your images to provide better critique. Specifically:
- Camera make and model
- Lens model
- Focal length (actual and 35mm equivalent)
- Aperture (f-number)
- Shutter speed
- ISO
- Exposure compensation
- White balance setting
- Flash setting
- The name of the editing application that last wrote the file, for example Adobe Lightroom, when the file records one. It is stored with the image version and is not shown on your public profile, in the gallery, or on a share page.
- Editing settings already applied to the file: when your export carries an Adobe XMP develop block, we read the slider positions it records (exposure, contrast, highlights, shadows, whites, blacks, texture, clarity, dehaze, vibrance, saturation, sharpening, noise reduction, tone curve, crop state, and the Camera Raw process version). The AI model is not shown these values. We use them only in an internal quality check that records where your sliders already sat when the critique was produced, so we can judge whether our editing advice is sensible for files like yours. They are stored with the image version and are never shown on your public profile, in the gallery, or on a share page.
We do not extract or store GPS coordinates, camera serial numbers, or other personally identifying EXIF fields. GPS data is actively stripped from all stored copies of your images.
2.4 AI Critique Data
When the AI analyzes your photograph, we store the full critique results, including:
- Artistic, competition, and potential scores
- FinalFrame Score (our composite quality metric)
- Bottleneck identification and editing suggestions (including software-specific instructions for your preferred photo editor)
- Composition analysis (eye flow points, tonal hierarchy, crop suggestions, bottleneck region coordinates)
- Key strengths, concept and technical assessments
- Stop-editing recommendations
- Capture tips, technique tips, and creative experiment suggestions
- Print recommendations
- Iteration comparisons when you upload revised versions
- Content safety verdict (see Section 2.6)
- Whether the image was flagged as likely AI-generated (based on absence of camera EXIF data)
- The AI model provider, model name, and prompt version used
- Token counts (input/output) for the AI request
- The raw JSON response from the AI model
2.5 Curation Data
If you use the photo curation feature (selecting your best images from a set), we store the session data including individual image scores, rankings, strengths and weaknesses, cohesion analysis, and sequence reasoning.
2.6 Content Moderation Data
Every image uploaded to FinalFrame is screened through OpenAI's content moderation endpoint (omni-moderation-latest) before critique. For any moderation outcome that matches a monitored category (“soft_block,” “hard_block,” and any “pass” that still flagged a category), we log the verdict, the flagged categories, and their confidence scores for audit and threshold calibration purposes. A clean “pass” with no flagged category is not logged. For hard-blocked content (severe policy violations), we additionally log: a cryptographic hash (SHA-256) of the image, your IP address, user agent, and the timestamp. This metadata is retained for law enforcement cooperation and platform safety. The image itself is deleted immediately and is not retained in any form. Non-hard-block moderation logs do not include IP addresses or image hashes.
Third-party content databases: moderation metadata (image hashes, flagged categories, scores) is stored in our own Supabase database for the purposes described above. A daily internal summary of moderation actions is also emailed to our company mailbox (see the Google Workspace entry in Section 5). An emailed summary stays in the mailbox it was delivered to, including after an account it names is deleted, and your rights under Section 8 still apply to that copy. We do not forward image hashes or moderation metadata to NCMEC, PhotoDNA, GIFCT, StopNCII, or any other external hash-matching database. We may cooperate with law enforcement authorities upon lawful request: in that case, hashes or metadata would be disclosed only in response to a specific legal process.
Automated detection scope (transparency disclosure). Our automated content moderation uses OpenAI's omni-moderation-latest model, which evaluates images for adult sexual content (sexual), violence (violence, violence/graphic), and self-harm content (self-harm, self-harm/intent, self-harm/instructions). It does NOT provide automated detection specific to child sexual abuse material; the sexual/minors category in the moderation API is text-only and is not evaluated against image content. We rely on user reporting (see Section 9.4 of our Terms of Service) and the adult sexual category with an admin review queue for borderline scores (0.50–0.75 band) as proximate signals. We may add a dedicated image-CSAM detection partner in the future and will update this section before doing so.
2.6a Automated Decision-Making (GDPR Art. 22)
Image uploads are screened by automated content moderation before any AI critique begins. These automated decisions can have a significant effect on you: they may restrict public sharing of your image, or, in the case of severe policy violations, result in your account being suspended and any active subscription being cancelled. We rely on automated screening because the volume and sensitivity of the material (including adult sexual content, graphic violence, and self-harm imagery) make pre-review by a human infeasible and unsafe.
Your right to human review. You have the right to obtain human review of any automated moderation decision that affects your account or your ability to share content. To request a review:
- If your account has been suspended, we email you when it happens, and that email includes a reference ID. Reply to it, or write to support@finalframe.photo with the reference ID (or, if you don't have it, the email address of the account), and a person at FinalFrame will review the decision. If you can still sign in, you can also use the “Request a review” form on your /suspended page, where the reference ID is pre-filled.
- Re-registration check. When a new account is created, we automatically compare a keyed hash of its email address against the re-registration signal described in Section 2.6c. If it matches, the new account is suspended straight away, without a person looking at it first. Two different people can occasionally share or inherit an address, so you have the same right to human review: reply to the email we send, or write to support@finalframe.photo.
- If sharing of a specific image was restricted (“soft block”), use the “Request a review” button under the restriction notice on that image's critique, comparison or collection page, or email support@finalframe.photo with the page URL. A person at FinalFrame will review the decision and reply typically within 3 business days.
2.6b AI Transparency (EU AI Act Art. 50)
The critique, score, tier, editing instructions, and any narrative text generated by FinalFrame are produced by AI models in OpenAI's GPT-5 family, operating on your image and optional EXIF metadata. The output reflects algorithmic analysis, not human judgement. It is intended as educational feedback, not as a professional appraisal, competition verdict, or legal document. The results may be incorrect, incomplete, or biased for reasons outside our control. You should use your own judgement when acting on any critique.
When you choose to publish an image to the public gallery (Section 6 of the Terms), its FinalFrame Score and tier are displayed publicly alongside the image, may appear on your public photographer profile, and can be shown in an embeddable badge you place on third-party websites you control. These scores remain an algorithmic assessment as described above; publishing is optional and reversible: unpublishing removes the public display, and the badge stops showing your statistics within approximately one hour.
OpenAI processes your image as a sub-processor on our behalf. See Section 5 (Third-Party Sub-Processors) for the specific processing role and data protection terms. Our data processing agreement with OpenAI is available on request.
2.6c Retention Periods for Moderation Actions
We retain data related to content-moderation actions for the following periods:
- Moderation event records (trigger category, image hash, decision verdict, timestamp, and where applicable IP address and user agent) are retained indefinitely under our legitimate interest (GDPR Art. 6(1)(f)) for platform-safety, recidivism detection, and potential law-enforcement cooperation. See Section 7.4 for what survives account deletion.
- Re-registration prevention signal: when an account is permanently terminated for a serious safety or Terms of Service violation, we retain a one-way keyed cryptographic hash (HMAC-SHA256, computed with a separate server-side secret key) of the associated email address. We store no readable email address: only this keyed hash, which cannot be turned back into your address and cannot be tested against guessed addresses without the key. We use it solely to prevent the terminated user from re-registering under the same address to evade the safety action. This signal is retained under our legitimate interest (GDPR Art. 6(1)(f)) in platform safety and abuse prevention, and is kept indefinitely while the termination stands, including after the original account is deleted (it would otherwise serve no purpose). If a review overturns the termination, or finds that the address now belongs to someone else, we delete it. It is never used for marketing, profiling, or any purpose other than blocking re-registration of a terminated account.
- Appeal and review-request submissions (whether made through the review-request form or the in-app feedback form's appeal category: the message you submitted and the reply we sent) are retained for the duration of the review and thereafter under our legitimate interest (GDPR Art. 6(1)(f)) for audit and regulatory-inquiry purposes; on account deletion these records are dissociated from your profile identity. We keep them for as long as the account's moderation history is relevant to a possible appeal, regulatory inquiry or dispute, and in any case no longer than 36 months, the retention period Section 7.4 sets for these records.
- Suspended-account data (photos, critiques, credits, account history) is retained indefinitely while the account is paused under review, so that a successful appeal can fully restore the account. If the appeal upholds the block and the account is therefore permanently terminated, non-severe accounts are retained only as long as necessary for our records and are then deleted; you may request deletion at any time via support@finalframe.photo. Section 9.5 severe violations have their content and images deleted immediately (except for the metadata expressly retained under Section 9.5 of the Terms of Service for law-enforcement cooperation).
2.7 Payment Data
If you subscribe to a paid plan (Pro at $19/month or Premium at $36/month) or purchase credit packs, payment processing is handled by Paddle (“Paddle”), who acts as our Merchant of Record. Paddle contracts through more than one legal entity and the one that is your counterparty depends on where you purchase from; see Terms Section 11.5. This means Paddle is the legal seller of the subscription; they process payments, collect applicable taxes (VAT, sales tax, GST), and handle chargebacks on our behalf. We store:
- Your Paddle customer ID and subscription ID (to link your account to your billing)
- The reference IDs Paddle assigns to your payments, refunds and chargebacks, and to the billing notifications it sends us about them, as part of your billing record (Section 7.4a)
- Your current plan type and Paddle product ID
- Credit balances (monthly and purchased)
We never see or store your full credit card number, CVV, or banking details. That data lives entirely within Paddle's PCI-compliant infrastructure. Invoices and receipts are issued by Paddle, not by FinalFrame.
2.7a Payment Retry Handling
When a subscription payment fails, we record the failure timestamp on your profile and retry the charge through Paddle for up to 30 days. During this retry window we send you up to three operational emails about the failure (first notice, midpoint reminder, and final notice before plan loss) so you can update your payment method. We also pause monthly credit refills beginning on the failure date: already-granted credits remain spendable, and credit balances are restored on successful payment. If all retries fail within the retry window, your plan reverts to Free and a final notice email is sent. We send these emails as part of our contract with you (GDPR Art. 6(1)(b), contract performance); they do not respect marketing-email opt-outs. The payment-failure timestamp is cleared when payment succeeds, when you cancel, or when a refund/chargeback is processed; otherwise it is purged after 180 days of account dormancy. We may also send you a pre-expiry notice up to 14 days before your card expires under the same legal basis.
Specific dunning email types we may send under this section:
- Payment retry reminder. When a recurring payment fails, we retry up to 7 times over 30 days and notify you mid-window. Legal basis: Art. 6(1)(b) contract performance.
- Payment final notice. Final notice before subscription downgrade if payment recovery fails. Legal basis: Art. 6(1)(b).
- Card expiring. 14 days before stored card expires, we send a reminder so you can update your payment method. Legal basis: Art. 6(1)(b).
- Payment recovered. Confirmation when a failed payment is successfully retried. Legal basis: Art. 6(1)(b).
- Plan downgraded by dunning. Confirmation when your subscription ends while a payment retry is still open and your plan moves to Free (no charges; existing credits preserved). Legal basis: Art. 6(1)(b).
2.7b Subscription Pause State
When you pause your subscription, we process pause-state data: pause scheduled date, pause start date, pause end date, and reminder-sent flag. Lawful basis: Art. 6(1)(b) GDPR (contract performance). We retain pause-state until the cap-enforcement window naturally expires (rolling 6 months) plus a 12-month dispute window.
2.8 Usage and Quota Data
We track:
- Weekly and monthly critique usage counts (to enforce plan limits)
- Credit balances and reset timestamps
- Individual usage events (event type, credit cost, timestamps, token counts)
2.9 Referral Program Data
If you participate in the referral program, we store:
- Your unique referral code
- Who referred you (a user ID link, not a public association)
- Whether the referral reward has been granted
- Referral count
- Referral audit records (referrer ID, referred ID, reward timestamps)
To prevent self-referral abuse, we normalize email addresses (stripping Gmail +alias suffixes) and compare them during referral processing. This normalized form is not stored; it is computed transiently during the check.
People who open your referral link see your display name on the sign-up page (“[your name] invited you”), unless your photographer page is hidden, in which case it says “A friend invited you”.
2.10 Public Gallery and Sharing Data
FinalFrame has an opt-in public gallery. If you choose to publish a project or curation session, the following becomes publicly accessible:
- Your display name, username, avatar, and bio
- Published photographs and their critique data
- Camera and lens information from your published photos
- Your profile view count
Your photographer page shows your display name and the profile details you have set to anyone who opens it, whether or not you have published anything, and share links you create link to it. You can hide it at any time in your account settings.
You can also generate share links (tokens) that make individual critique results accessible to anyone with the link. A share page and its preview image show your display name as the author, even if your photographer page is hidden. You can unpublish projects or revoke share links at any time.
After you revoke a share link, the link becomes inaccessible immediately. However, cached previews on third-party platforms (WhatsApp, Facebook, X, Discord) may persist for 1–7 days. FinalFrame does not control third-party caching behavior.
Image URL expiry after revocation. When a viewer loads a share page, their browser receives a time-limited signed URL pointing directly to the image file. If you revoke the share link or delete the critique after a viewer has already opened the page, the share page itself stops loading for new visitors immediately, and the viewer can no longer obtain a fresh signed URL. However, a signed URL already issued to a browser remains fetchable from our storage provider until it expires. How long that is depends on the kind of image: at most 3 hours for images served on shared and public gallery pages, at most 3 hours for your profile photo and cover photo wherever they appear, including on your own account pages while you are signed in, and at most 1 hour for the other images on your own account pages. A thumbnail we embed in an email to you is signed for up to 7 days, so that copy can remain loadable in your own mailbox for that period. After the window that applies to the image closes, the image file can no longer be fetched from our storage provider by any previously issued URL. Some pages show a resized copy instead, which our hosting provider, Vercel, makes from the signed URL and keeps in its cache; anyone who requests the copy’s address, which contains the signed URL, receives it. A copy counts as current for 1 hour, or for the lifetime of the signed URL it was made from if that is longer, counted from when the copy was made. Copies of your profile photo and cover photo are the exception: they count as current for 1 hour. So a copy made just before the window closes stays current for up to 3 hours after the window closes for an image on a shared or public gallery page, and for up to 1 hour for your profile photo, your cover photo and the other images on your own account pages. After that, Vercel can still serve the old copy while it tries to refresh it, and the refresh fails because the signed URL has expired. Vercel’s documentation does not say how long it keeps or serves an expired copy, so we cannot give you an end time. Our emails load their thumbnail directly, not through this cache.
2.11 Challenge Data
If you participate in photography challenges, we store your entries, constraint scores, and feedback linked to the challenge.
2.12 Progress Insights and Coaching Data
As you use FinalFrame over time, we generate personalized progress insights and coaching briefs. These include a narrative assessment, focus areas, shooting and editing missions, patterns observed in your work, and a photographer identity label. This data is derived from your critique history and stored in your account.
2.13 Feedback Data
If you submit feedback through the in-app feedback form, we store your message, a screenshot (if you choose to include one), the page URL you were on, and your browser user agent string.
If you cancel your subscription, we ask for an optional reason (selected from a preset list, with an optional free-text field). This is stored alongside your feedback data to help us improve the service.
Lawful basis: We collect optional cancellation reasons to improve the product, under GDPR Art. 6(1)(f) legitimate interest. Our interest in understanding churn does not override your rights, because the data is minimized (enumerated category by default) and the free-text portion is purged automatically.
Retention: The enumerated reason code (e.g. “too_expensive”, “not_using_enough”, “other”) is retained with your account for as long as the account exists. Any free-text response you provide in the “Other” field is automatically purged after 90 days.
Right to object (GDPR Art. 21): You can request immediate purge of your cancellation free-text by emailing support@finalframe.photo. We will process the request within 30 days, and typically within a few business days.
2.13a Mid-Cycle Plan Change Consent Records
When you change your plan mid-cycle in a way that places an immediate charge, such as upgrading to a higher tier (for example, Pro to Premium, which unlocks the Coaching Brief as an additional feature), or changing your billing frequency (for example, monthly to annual, which commits you to a new, longer minimum term), we write a dedicated consent record to our consent_events table capturing your express request that the change take effect immediately, during the 14-day withdrawal period, and your acknowledgment of how that affects the right under EU Directive 2011/83/EU Art. 8(8), 14(3) and 16(a): if you withdraw after starting to use the change, you pay in proportion to the credits you have spent, and the right ends early only once you have spent every credit the change provided, as set out in Section 11.8 of our Terms.
Purpose. Record of your express request for immediate performance of the upgraded services (for example, Coaching Brief on Premium) and of the acknowledgment that accompanies it. Required under GDPR Art. 7(1) accountability and the Consumer Rights Directive 2011/83/EU: Art. 8(8) obliges us to obtain that request and acknowledgment, and Art. 14(3) and 14(4)(a) make the amount you owe for the part you used depend on our being able to show that we did. This is a separate consent moment from the request you made when you first subscribed (recorded under action “withdrawal_waiver_accepted”) and from the cookie- consent log described in Section 9.
Data retained. The action type “withdrawal_waiver_upgrade”, the timestamp, your IP address, your user agent string, the from-plan identifier, the to-plan identifier, and the price amount shown to you on the order screen at the moment of consent (retained as evidence that the price you consented to is the price you were charged). No payment-card data, no image data, and no critique content is written to this row.
Retention. 6 years from the consent event, aligned with the German Handelsgesetzbuch § 257 commercial record-keeping requirement (which applies to Crypto Brains DOO in respect of EU customer-facing contracts and may be invoked to prove that your express request and acknowledgment were obtained before performance began). After 6 years, the record is purged.
Lawful basis. GDPR Art. 6(1)(c): legal obligation to record consumer consent under Art. 7(1) GDPR together with the national transpositions of Consumer Rights Directive 2011/83/EU Art. 8(8), 14(3) and 16(a) (for example, § 356 Abs. 5 Nr. 2 and § 357a Abs. 2 BGB in Germany, Art. L221-25 and L221-28 1° Code de la consommation in France).
Your rights. You can request a copy of your upgrade-consent records through the self-service data export in Account Settings (which covers the consent_events table under Section 8.1), or by emailing support@finalframe.photo. Because this record is retained under a legal obligation, we cannot delete it before the 6-year retention period ends, even on an Art. 17 erasure request; we will restrict processing on request instead (Art. 18).
2.13b Critique Rating Feedback
Under each critique you can rate it from one to five stars. Alongside the rating you may optionally pick a reason from a preset list (for example “Tier or score felt wrong”, “It misread the photo”) and add a free-text note of up to 300 characters. Both the reason and the note are optional at every rating, and we store them with the rating, your account and the critique they refer to.
Marking a point that doesn't match your photo: Under the main issue in a critique, and under a permanent-limit note when there is one, you can mark that point as not matching your photo and pick a reason from a short preset list. We store which point you marked, the reason, your account and the critique. There is no free-text field. A mark follows the rules in this section for ratings, with one difference: it is not included in the daily internal summary. So it has the same purpose and lawful basis, it is private to you and FinalFrame and never shown to anyone else, it is never fed back into the AI, and it never changes your critique, score or credits. You can change the reason at any time from the critique, and the retention and removal rules below apply to marks as they do to ratings.
Lawful basis: We collect critique ratings to review and improve the quality of our AI critique, under GDPR Art. 6(1)(f) legitimate interest. Our interest in knowing where the critique is wrong does not override your rights: rating is entirely optional, the reason and note are optional within it, and the data is used only to review critique quality. The note field also asks you to keep it about the critique rather than about people, so we are not inviting information about anyone else.
Visibility: Ratings are private. They are never shown on your public profile, in the gallery, on a shared critique link, or to any other user, and they are never fed back into the AI to change how it critiques your work. Only FinalFrame sees them, in our admin tools. A daily internal summary emailed to us records that a rating arrived, its star value, a link to the critique, and any reason category you selected. Where a rating is low, that summary also counts reason categories by photography genre across accounts, and includes links to a small random sample of low-rated critiques for us to read. Your written note is not copied into that summary.
Retention: In our database, your rating, the selected reason and any free-text note are retained for as long as the critique they refer to exists. Deleting your account removes them immediately. Deleting the photo removes them once that photo is purged, which happens after its 30-day recovery window has passed. We run no separate retention window for rating feedback.
The emailed summary is not covered by those deletions. An email that has already been sent cannot be recalled by deleting a photo or an account, so each daily summary stays in the mailbox it was delivered to (summaries now go to our Google Workspace mailbox, see Section 5) with whatever it recorded at the time: the star value, the link, any category selected, the genre-and-category counts, and any sampled links. Your written note is not in it. Your rights under Section 8, including erasure, still apply to that copy.
Changing or removing it: You can change your rating at any time from the critique itself, which overwrites the previous one, including the reason and note. To have a rating removed entirely, email support@finalframe.photo. We will process the request within 30 days, and typically within a few business days.
2.13c Cancellation and Withdrawal Declarations (no-sign-in pages)
Two pages of our site take a declaration without a sign-in, because the law that requires them forbids one: the “Cancel your subscription” page (German § 312k BGB) and the “Withdraw from contract here” page (Directive 2011/83/EU Art. 11a). On each we record what you type (your name, the email address of the account, your description of the subscription or purchase, and the address for our confirmation), the page language, the date and time we received it, and the IP address and browser identification of the submission. We use the email address to find the account it names and, where one exists, send a copy of our confirmation to that account's own address, so the holder learns of a declaration made in their name. For a withdrawal we also record, at the moment of receipt, the credits each affected purchase provided and how many had been used, because that fixes the proportional amount under Art. 14(3) of the Directive, and we later record what we did with the declaration. Lawful basis: sending the confirmation is a legal obligation (GDPR Art. 6(1)(c)); keeping the record afterwards rests on our legitimate interest in being able to show what reached us and when (Art. 6(1)(f)). Retention, and what survives account deletion, is in Section 7.4. If you did not make a declaration sent in your name, reply to the copy we sent you or email support@finalframe.photo.
2.13d Free Plan Upgrade Question
When a Free account that has used all of its credits closes the upgrade window without upgrading, the window may ask one optional question, once: what the main reason is for not upgrading today. You answer with one tap from a short preset list (for example, that the price is the reason), or close the window without answering. There is no free-text field. We store the answer you picked, the date, and whether the free credits for uploading an edited version were still available to your account at the time. We also record that the question was shown to your account, and when, so that we never ask it again.
Lawful basis: We ask so that we can understand why Free accounts do not move to a paid plan and improve the product and its pricing, under GDPR Art. 6(1)(f) legitimate interest. Our interest does not override your rights: answering is entirely optional, the answer is one choice from a fixed list, it is never used for marketing or to decide anything about your account, and we delete it after a fixed period.
How we use it: We count the answers, by answer and by the campaign, if any, that brought each account to FinalFrame (the acquisition fields in Section 2.15a). What we keep from those counts is totals only, with no account identifiers. Your answer never changes your plan, your credits or any price shown to you. It is never shown to anyone outside FinalFrame, and it stays in our own database: we do not send it to our analytics provider.
Retention: We delete your answer, its date and the credit detail 12 months after you give your answer, or 12 months after the question was shown if you did not answer. The record that the question was shown to your account is kept while your account exists, so that we do not ask again. Deleting your account removes all of it immediately.
Removing it: To have your answer removed sooner, email support@finalframe.photo. We will process the request within 30 days, and typically within a few business days. You can also object to this processing under GDPR Art. 21 (Section 8).
2.14 Demo Session Data
If you try a demo critique without an account, we store a demo session linked to your IP address, the critique results, and the demo image. Demo images are cleaned up separately from account data. If you create an account, a demo critique you ran on this device may be linked to your new account so it appears in your dashboard.
Lawful basis. We process your demo image and the IP address under our legitimate interest (GDPR Art. 6(1)(f)) in providing the free trial you requested and in preventing abuse of it. Because the demo is a transient, one-off critique you initiate, we rely on legitimate interest rather than consent; there is no standing relationship to manage and no consent-withdrawal mechanism for data this short-lived; you can instead ask us to delete a demo session at any time (see below).
Sub-processor. Before we generate the critique, your demo image is sent to OpenAI (US) for content moderation and AI analysis, exactly as it is for account critiques. OpenAI acts as our sub-processor for this step; the transfer safeguards (Standard Contractual Clauses and the EU-U.S. Data Privacy Framework) are described in Section 5 (Third-Party Sub-Processors) and Section 6 (International Data Transfers).
EXIF metadata. As with account uploads, we read a limited set of photographic and editing metadata from your demo image (camera make and model, lens, exposure settings, and any editing settings the file records) to inform the critique. GPS location data is always stripped and is never stored. See Section 2.3 for the full list of EXIF fields we read.
IP address retention. What happens to the IP address recorded with a demo session depends on whether you go on to create an account:
- Claimed demos: if you create an account and the demo critique is linked to it, the abuse-prevention purpose for the IP address is spent, so the IP address is erased once the demo is claimed (by a daily background job). The critique itself migrates to your account and follows your account's retention schedule.
- Unclaimed demos: if the demo is never linked to an account, we retain the IP address for up to 30 days for abuse-prevention (rate-limiting and detecting repeated misuse of the free trial). After 30 days, the entire demo session (image, critique results, and IP address) is deleted. See Section 7.6 for the retention summary.
These periods apply to the IP address itself. Our product analytics separately keep a daily-changing hash of it (see Section 2.15a), and when a demo fails our server logs record the same hash. Our hosting provider, Vercel, keeps those server logs for up to 30 days and then deletes them.
2.15 Cookies and Local Storage
FinalFrame stores your cookie consent preference (“accepted” or “rejected”) in localStorage and in a matchingff_consent cookie, so the choice can be honoured on our servers as well as in your browser. Supabase Auth uses its own cookies/storage for session management. FinalFrame also remembers some interface choices you make on a device in localStorage, and keeps profile changes you have not yet saved in the sessionStorage of the browser tab you are editing in. See Section 9 for full details.
2.15a Telemetry and Analytics Stream
FinalFrame uses PostHog (EU Cloud instance at eu.i.posthog.com, hosted in Frankfurt, Germany) to log structured product-analytics events. This subsection names every event our servers send, grouped by purpose, and discloses the data fields each group carries (an event carries some or all of the fields listed for its group), the lawful basis for each, and your rights relating to this data. Events your browser sends are covered by Section 9.2 and are sent only if you accepted analytics cookies; the first row of the table shows one of them, the sign-up event.
Event types and lawful basis
| Event | Data fields | Lawful basis |
|---|---|---|
signup_completed (sent from your browser) | method, whether a confirmation email is needed, whether you arrived through a referral link, source (direct, demo or shared link), whether the page ran in an in-app browser, and the demo tier or call to action that brought you, if any | Art. 6(1)(a): your consent. Sent only if you accepted analytics cookies. |
signup_provisioned (acquisition fields) | acquisition_source, acquisition_medium, acquisition_campaign (marketing parameters from the link you arrived through), landing_referrer_host (the host name of the referring site only, e.g. news.ycombinator.com; never the full address, path, or query), signup_device (phone, tablet or computer), referral (whether you arrived through a referral link), demo_converted (whether you tried the demo first), plan, locale | Art. 6(1)(f): legitimate interest. We record which marketing channel brought you to FinalFrame, read once from the page URL and the referring site (when you sign up, or on your demo visit if you ran a demo first) and, only if you accepted cookies, from the first-touch campaign cookies described in Section 9.2, so we can measure which acquisition channels are effective. We store the referring site’s host name only, never the full referrer URL. We do not profile you or make any automated decision from this data, and without your consent we set no cookie to collect it. Our interest is understanding how people find the product; it is proportionate given the data is minimal and internal-only. You have the right to object to this processing at any time (Art. 21(1)): see Section 8 (Your Rights). |
Using the product: critique_started, critique_completed, critique_failed, paid_user_first_critique_completed, iteration_started, iteration_completed, iteration_failed, duplicate_upload_resolved, near_duplicate_measure, near_duplicate_reupload, over_edit_visual, comparison_started, comparison_completed, comparison_failed, comparison_disqualified_refund, curation_started, curation_completed, curation_failed, curation_iteration_completed, curation_iteration_failed, curation_result_viewed, curation_critique_cta_clicked, coaching_brief_unlocked, coaching_brief_emitted, coaching_brief_refresh_gated, share_link_created, gallery_published, challenge_entry_created, badge_rendered, project_delete_storage_deferred | user_id; your plan; the feature and the options you chose (lane, curation goal, number of images, the screen you started from, how the credit was paid for and, for a new version, your credit balance in broad bands); the identifiers of the project, version, critique, curation set, image or challenge concerned; the result in summary form (score and tier, the categories the critique named, the AI model that wrote it, whether it judged the image not to be a photograph or to be AI-generated, and the outcome of our automatic checks on it, such as over-editing or a suggested crop that did not fit; for a comparison, which image came out ahead and how confidently, both scores and how many categories each won; for a curation, summary counts and scores for the set; for a Coaching Brief, its main focus area and how many critiques it drew on); for a new version, how its score and tier changed; when an upload closely matches one of your earlier ones, measurements of how similar the two are (never the images); when something fails, the reason and whether your credit was refunded; for a share link, a one-way hash of its token (never the link itself) and when it was created; and, each time your embeddable badge is loaded, the count and tier it showed | Art. 6(1)(f): legitimate interest in measuring how the features are used, whether they work and where they fail, so we can fix and improve them. These events are identified by your user ID, never by your email or name. You have the right to object to this processing at any time (Art. 21(1)): see Section 8 (Your Rights). |
Credits, limits and account checks: credit_limit_hit, burst_limit_hit, credit_reset_lazy, concurrency_throttled, verify_gate_blocked, signup_alias_collision_blocked | user_id; your plan; credits remaining, unused or carried over, including at the monthly reset, and the day of your billing cycle; which limit you reached, its size and time window, how long until it frees up and, for the credit limit, how long ago you first submitted a new version of a photo; which action you tried before confirming your email address; and, when a sign-up is stopped because a confirmed account already uses the same mailbox, the kind of email that was requested (never the address) | Art. 6(1)(f): legitimate interest in keeping usage limits fair, the service stable under load and sign-ups free of abuse, and in checking that these controls work. You have the right to object to this processing at any time (Art. 21(1)): see Section 8 (Your Rights). |
Referral program, between accounts: referral_code_created, referral_signup_linked, referral_signup_skipped, referral_reward_granted, referral_reward_received, referral_cap_exceeded | user_id; the reward credits; the referrer’s number of referrals when the reward limit is reached; and, when a referral is not credited, the reason (an unknown code, a suspended account or a self-referral) | Art. 6(1)(f): legitimate interest in running the referral program and preventing referral fraud. You have the right to object to this processing at any time (Art. 21(1)): see Section 8 (Your Rights). |
Billing and subscription: checkout_started, subscription_activated, subscription_renewed, subscription_changed, subscription_reactivated, credits_purchased, payment_recovered, cancellation_initiated, cancellation_confirmed, subscription_cancel_requested, save_offer_3mo_accepted, subscription_cancel_reversed, subscription_cancelled, subscription_pause_requested, subscription_pause_scheduled, subscription_pause_canceled, subscription_paused, subscription_resume_requested, subscription_resumed, refund_processed, subscription_refunded, subscription_partial_refunded, credit_pack_refunded, subscription_chargedback, chargeback_reversal_received | user_id; the plan or credit pack (and, on a change, the plans before and after), billing interval, price, amounts paid or refunded and their currency, and the payment provider; renewal number and days since sign-up, since your last renewal or since you cancelled, and days left in the billing period; credits granted, used, unused and carried over, and how much of your allowance you used; a discount code when one was applied; the Paddle transaction or event number; the dates a pause starts and ends or a subscription resumes; for a refund or chargeback, its kind and whether it came within 24 hours of activation; and, for a cancellation or a pause, only the reason you picked from our list, sent as a code (e.g. “too_expensive”). Never your email, name, payment details or a free-text answer. | Art. 6(1)(f): legitimate interest in understanding conversion, renewal and churn so we can price and improve the service. Free-text cancel reasons are not forwarded to PostHog. Per-critique AI cost stays in our own records and is not sent to PostHog. You have the right to object to this processing at any time (Art. 21(1)): see Section 8 (Your Rights). |
Free demo and referral-link events: demo_critique_completed, demo_conversion_started, demo_conversion_success, demo_conversion_failed, demo_ip_fallback_claim, referral_link_visited, referral_invalid_code_redirect | In place of a user ID: a one-way hash of your IP address combined with the day’s date, so it changes every day. With it: for a finished demo critique, its lane, tier and score; when you sign in with no critiques yet and we check for a demo to import, whether we found one for you, the imported project’s ID, how long it took and, if nothing was imported, the reason; when a demo is matched by IP address rather than by your browser, the demo’s ID and age, the matching window, which lookup matched and whether we accepted the match. Opening a referral link records only that it was opened and whether its code was valid. The internal critique quality checks (the posthoc_gate row below) also run on demo critiques, under the same hash. | Art. 6(1)(f): legitimate interest in measuring whether the free demo and referral links lead to sign-ups, and in spotting when a demo is claimed across a shared network (an office, or a mobile carrier that puts many people behind one address) so that nobody imports a stranger’s demo. The hash is pseudonymous, not anonymous: it can be linked back to the IP address it came from, so it remains personal data. These events use no cookie and are sent whether or not you accepted cookies. We keep them for 12 months, like all our PostHog data (see “Retention” below). You have the right to object to this processing at any time (Art. 21(1)): see Section 8 (Your Rights). |
posthoc_gate (internal critique quality checks) | user_id, gate_event (which check fired, an enumerated name such as a crop-suggestion consistency check, an over-editing check, a slider-sanity check, or an unrecognised-editing-software probe) and that check's own numeric or enumerated result. For the slider-sanity check this includes the slider positions recorded in your file (Section 2.3) and the values the critique suggested. For the editing-software probe it includes the software name string recorded in your file's metadata, which metadata tag carried it, the software agents named in the file's XMP edit history, the XMP namespace names present, the container type, and the camera model. We do not send the image itself. Beyond the fields named above, individual checks can also record one or more short excerpts of the critique text the check evaluated, the internal storage key and record identifiers of the image, project or critique the check ran on, a short label the check itself generated naming the part of the photograph it examined (for example the subject's nearer eye), and the check's own diagnostic values; which fields each check can send is determined by our code, not by who you are. The same events are also written to our server logs, which Sentry (Section 7) captures. Our hosting provider, Vercel, keeps those server logs for up to 30 days and then deletes them. | Art. 6(1)(f): legitimate interest in measuring and improving critique quality, for example teaching our editing-software registry a tool it could not name. You have the right to object to this processing at any time (Art. 21(1)): see Section 8 (Your Rights). |
New profile columns
As part of the analytics pipeline, we store the following additional fields on your profile record:
- signup_device: whether you signed up on a phone, a tablet or a computer, worked out once from your browser identification (user agent) when your account was created, and also sent with the
signup_provisionedevent. Used to compare how people who sign up on each kind of device go on to use FinalFrame. Lawful basis: Art. 6(1)(f) (legitimate interest in product analytics); no cookie is involved. You may object at any time under Art. 21(1): see Section 8. - first_paid_at: the timestamp of your first paid subscription activation. Used to compute Free→Paid conversion cohorts. Lawful basis: Art. 6(1)(b) (contract performance: denormalized for billing coherence) + Art. 6(1)(f) (business analytics).
- acquisition_source, acquisition_medium, acquisition_campaign, landing_referrer_host, which marketing channel brought you to FinalFrame: UTM parameters from the link you arrived through, plus the referring site’s host name only (e.g.
news.ycombinator.com; never the full address, path, or query). Read once from the page navigation (on the visit where you sign up, or, if you ran a demo first, on that demo visit, then carried to your account through the demo cookie in Section 9.1) and, only if you accepted cookies, from the first-touch campaign cookies described in Section 9.2. Without your consent no campaign cookie is set or read. Lawful basis: Art. 6(1)(f) (legitimate interest) in measuring which acquisition channels are effective, including for values that came from the campaign cookies, whose storing and reading in your browser needed your consent; we do not profile you. You may object at any time under Art. 21(1): see Section 8.
AI call cost tracking
We maintain an internal ai_calls table that logs per-request AI cost data (model, token counts, computed cost in USD, call type, success/failure). This table is used exclusively for internal cost monitoring and is never exposed to users via any API or export. It is subject to column-level access controls that prevent any authenticated user from reading it via the database API. Lawful basis: Art. 6(1)(f): legitimate interest in monitoring operational costs. Retention: 24 months, a period we set ourselves for this internal table. It is separate from, and not tied to, the period that applies to our PostHog analytics (see the “Retention” subsection below). Rows that age past this window are purged automatically by a daily background job. These internal cost-monitoring rows are not financial accounting records: Paddle, our payment processor and merchant of record, holds the invoices and financial records subject to longer statutory retention.
PostHog as recipient and data residency
PostHog Inc. (US-domiciled) is our analytics sub-processor. We use PostHog's EU Cloud instance (eu.i.posthog.com), which stores all event data in Frankfurt, Germany. A Data Processing Agreement (DPA) and Standard Contractual Clauses (SCCs) are in place to cover any US-domiciled data access by PostHog staff.
Retention
We retain PostHog event data for no longer than 12 months, the retention period of the PostHog Cloud plan we have chosen for that purpose, after which PostHog deletes it. Our internal AI cost-monitoring data has its own, separately stated period (see the “AI call cost tracking” subsection above), which is not tied to this one.
Right to erasure (§5 cross-reference)
When you submit a deletion request under GDPR Art. 17 (available in Account Settings or by emailing support@finalframe.photo), we delete:
- All relevant columns from your profile record (
first_paid_at,acquisition_source,acquisition_medium,acquisition_campaign,landing_referrer_host) - Your PostHog person record and all associated event history via PostHog's person-deletion API
Events recorded under a hashed IP address (the free demo and referral-link row above) are not part of that record, so deleting your account does not remove them; PostHog deletes them at the end of the retention period above. Once your account is gone, or if you never made one, we cannot link them to you on our own: if you want them deleted sooner, email support@finalframe.photo with the IP address and the dates concerned, and we will delete the matching events (Art. 11(2)).
See Section 8.1 (Right to erasure) and Section 7.4 (Account Deletion) for the full deletion cascade.
Regulatory references
Our marketing-attribution capture reads UTM parameters and the referring host from page navigation, not from device storage, so that read falls outside the consent gate of ePrivacy Art. 5(3) (EDPB Guidelines 2/2023 on technical storage and access); the processing of that data rests on legitimate interest (Art. 6(1)(f)). CJEU Planet49 (C-673/17) governs cookie storage and access, which this navigation-read path deliberately avoids. The one exception is the first-touch campaign cookies of Section 9.2: storing UTM values in your browser between visits is storage within ePrivacy Art. 5(3), so those cookies are set only after you accept the cookie banner and are removed when you reject or reset your cookie preferences. The legitimate-interest basis is documented in our internal Legitimate Interest Assessment (LIA) referenced in the DPIA §11.
2.16 Newsletter
We do not currently offer a newsletter or any other email list you can sign up for, and we hold no newsletter subscriber data. If we introduce one, we will update this section before we collect any sign-ups. The emails described in Sections 2.16a to 2.18 go only to account holders, on the lawful basis stated in each section.
2.16a Monthly Recap (Existing Customers)
Monthly progress recap email: a once-a-month summary of your critique activity and progress, sent only to existing paying customers who are drifting: users on a Pro or Premium plan who were active in the last 60 days but not in the last 14 days. This is lifecycle mail about the paid service you already use, not a general newsletter, so it does not use double opt-in.
Lawful basis (two layers). The permission to send it rests on the existing-customer “soft opt-in” under the ePrivacy Directive 2002/58/EC Art. 13(2) (and its UK PECR Reg. 22(3) equivalent), which applies where (a) we obtained your contact details in the course of a sale of a similar product, (b) every message markets only our own similar photography-critique service, and (c) you are offered a simple, free means to refuse this use both when we collect your details and at any time afterwards. The processing of your contact details to prepare and send it rests on our legitimate interest (GDPR Art. 6(1)(f); Recital 47 expressly recognises direct marketing as a legitimate interest). As in Section 2.17, legitimate interest is the basis for processing your data, not a licence for the marketing send itself: the send is permitted by the soft opt-in above.
On by default; opt out at any time. Because it relies on the soft opt-in rather than your explicit consent, this email is on by default (opt-out) for the eligible paying cohort. You were first given a simple, free way to refuse marketing email when you created your account, before any recap is sent, and you can turn this email off at any time thereafter using the emailMonthlyRecap toggle in your account's Email Preferences settings, or the one-click unsubscribe link in every recap email; under GDPR Art. 21(2) an objection to direct marketing is always upheld at once. The email is also suppressed automatically for users on a content-moderation pause, and for any address on our email suppression list, regardless of preference state.
2.17 Win-Back Email Consent
When you cancel a paid subscription, we offer an optional checkbox to receive a short series of win-back emails (up to 3 messages, the last about 60 days after your plan ends). We only send these emails if you explicitly tick the opt-in checkbox at the cancellation confirmation screen, or turn on Win-back emails in your account's Email Preferences settings: pre-ticked boxes are never used.
Lawful basis: Explicit consent (GDPR Art. 6(1)(a)). This is a separate consent moment from the cancellation-reason retention described in Section 2.13, which relies on legitimate interest (Art. 6(1)(f)) to analyse churn patterns. The win-back program is marketing; the reason retention is product analytics. We keep them legally distinct.
Data we log: A timestamp of when you opted in, the IP address and user agent at the moment of consent when you opt in at the cancellation screen (for Art. 7(1) demonstrability), and each win-back email we send to you via our standard email event log. We also record each time you withdraw win-back consent (the date and time of the withdrawal), so that both the start and the end of your consent are demonstrable.
What these emails contain: The 30-day win-back email may remind you what is waiting in your account, using your own account data: how your critique scores changed and how many projects you have and, if your plan before you canceled was Premium, the photographer identity label and the title of the main focus area from your latest Coaching Brief (Section 2.12). The Coaching Brief lines are left out when the brief is not in your account's language. This uses no data beyond what is already stored in your account; it goes only to your own email address, through our email provider (Resend, Section 5); and withdrawing consent stops it with the rest of the series. Win-back emails sent on the soft opt-in basis described below contain none of it.
How to withdraw consent: Click the unsubscribe link in any win-back email (ends the entire 3-message series instantly), toggle off win-back emails in your account settings, or click the global unsubscribe link in any of our marketing emails. Per GDPR Art. 7(3), withdrawing consent is as easy as giving it.
Involuntary (failed-payment) churn: soft opt-in basis. If your paid subscription ends not because you actively canceled but because we could not collect payment after the full dunning retry cycle, we may send the same short win-back series to the email address you gave us when you subscribed. For this cohort the lawful basis is not explicit consent and is not legitimate interest (GDPR Art. 6(1)(f) does not license a direct-marketing send): it is the existing-customer “soft opt-in” under the ePrivacy Directive 2002/58/EC Art. 13(2) (and its UK PECR Reg. 22(3) equivalent). That exemption requires that (a) we obtained your contact details in the course of a sale of a similar product, (b) every message markets only our own similar photography-critique service, and (c) you are offered a simple, free means to refuse this use: available at any time via your account settings, the global marketing-unsubscribe link, and a one-click unsubscribe in every message we send.
How you can refuse: at signup and at any time: The simple, free opportunity to refuse these emails is offered to you at the point of signup: when you create your account we tell you we may send occasional marketing emails about the FinalFrame service and give you a one-step way to opt out before any is sent. That same refusal also covers this win-back series. You can additionally opt out at any later time via the win-back toggle in your account settings, the global marketing-unsubscribe link, or the one-click unsubscribe link in every win-back message. Opting out at signup, or using the global unsubscribe at any time, stops this series together with all our other marketing email. The footer of win-back emails to this cohort identifies you as a former FinalFrame subscriber rather than claiming you opted in, so the basis is never misrepresented.
Right to object (GDPR Art. 21(2)): immediate opt-out. You have an absolute right to object to direct marketing at any time. For the soft opt-in cohort, exercising that right via any of the routes above stops the entire win-back series immediately and with no further messages; we do not require a reason and there is no balancing test: an objection to direct marketing is always upheld at once.
2.18 Onboarding and Activation Emails
When you create a FinalFrame account, we send a short series of onboarding emails over your first few days (currently up to three messages within roughly 72 hours): getting-started guidance, a walkthrough of core features, and an explanation of what the Premium tier and Coaching Brief add. Their purpose is to help you activate and get value from the service you signed up for.
Lawful basis. These are first-party service and activation communications about the product you registered for: not a generic newsletter and not third-party marketing. We rely on performance of a contract (GDPR Art. 6(1)(b)) and our legitimate interest in helping new users successfully adopt the service (Art. 6(1)(f)). We do not rely on the existing-customer “soft opt-in” (ePrivacy Directive Art. 13(2)). That basis applies only where contact details were obtained in the course of a sale, and a free signup is not a sale. We do not treat the default-enabled state as your consent under Art. 6(1)(a).
How to opt out (at any time, before or after any message). Toggle off Getting started emails in your account's Email Preferences settings, click the one-click unsubscribe link in any onboarding email, or use the global marketing-unsubscribe link. Opting out stops the remaining series immediately. These emails are also suppressed for any account on a content-moderation pause, regardless of preference state.
Right to object (GDPR Art. 21(2)). You have an absolute right to object to direct marketing at any time. Exercising it via any route above stops the onboarding series at once: no balancing test, no reason required.
Data we log. Each onboarding email we send is recorded in our standard email event log (the message type and a timestamp), used to sequence the series and to honour your opt-out.
2.19 Contact Email and Messages to Photographers
If you are a photographer. Your profile has an optional contact email field. It is never displayed on the page itself. Setting it enables two separate things, and you can control each one:
- Reveal to signed-in visitors. A visitor who is signed in to a FinalFrame account can press a button on your profile to reveal and copy the address. Anonymous visitors cannot; they are not shown that the address exists. Reveals are rate-limited per viewer. To switch this off, clear the contact-email field.
- Relayed messages from a contact form. Any visitor, including an anonymous one, can write to you through a form on your profile. We deliver their message to your contact email; the sender never sees your address. To switch this off while keeping the reveal above, turn off Client inquiries in your account's Email Preferences, or use the one-click unsubscribe link in any relayed message. Turning it off removes the form from your public profile entirely.
We email the address to confirm it belongs to you. When you save a contact email, we send a short message to that address asking whoever reads it to confirm. Until someone does, the contact form does not appear on your profile and we relay nothing: so an address entered by mistake, or by someone else, never receives forwarded messages. The confirmation link is valid for 7 days, and saving the address again sends a new one. We limit how many of these confirmation messages any one address can receive per day.
If you received a confirmation request you did not expect. Someone entered your address on a FinalFrame profile. Ignore the message and nothing happens: no messages are relayed to you and no account of yours is created or changed. The message tells you only that an address was entered; it does not disclose who entered it.
If you are writing to a photographer. When you submit the contact form we collect and store your name, your email address, your message, your IP address, and the time of submission. Your name, email address and message are passed on to the photographer: your email address is placed in the message's reply field so that they can answer you directly, and their reply comes from their own address, not through FinalFrame. We do not verify that the address you enter belongs to you, we do not send you anything at that address, and we do not add you to any mailing list. The IP address is retained for abuse prevention only.
Lawful basis. Legitimate interest (GDPR Art. 6(1)(f)) in operating a correspondence channel that both parties want: the sender chose to write, and the photographer chose to publish a contact address and to leave the channel open. This is correspondence delivery, not marketing; we do not use a message, or a sender's address, to send FinalFrame's own promotional email.
Retention. Relay records, including refused submissions, are permanently deleted after 90 days (Section 7.7). The delivered message itself lives in the photographer's own mailbox after that point and is outside our control. Reporting a message does not extend that window: the relay record is deleted on the same schedule either way, and the copy you forward to support@finalframe.photo is what we work from.
Abuse. Automated bot checks, per-sender and per-recipient rate limits, and content limits apply to every submission. To report an abusive message, forward it to support@finalframe.photo: do not reply to it, since replying discloses your own address to the sender.
2.20 Notifications on Your Devices and the Installed App
Off by default. FinalFrame can tell you, on a device you choose, when a critique or an iteration critique is ready. Nothing is sent until you tap a button that says so and your browser then asks for its own permission. We never use this channel for marketing or reminders; it carries exactly two events, “your critique is ready” and “your iteration critique is ready”.
What we store when you turn it on. Your browser gives us a subscription: a delivery address (a web address at your browser's push service) and two encryption keys that belong to that browser. We keep it linked to your account, together with the device class (iPhone or iPad, Android, desktop or other) and the language you were using, so the notification is written in that language. If you turn notifications on on several devices, each one receives them. We delete a subscription when you turn notifications off on that device, when you sign out from the menu (what we keep then is described under “Signing out and back in” below), when the push service tells us it no longer exists (for example after you block notifications for FinalFrame in your browser), after repeated failed deliveries, or when you delete your account (Section 7.4). If someone else signs in to FinalFrame in the same browser and turns notifications on, the subscription moves to their account and is no longer linked to yours.
Who carries the message. A notification travels through the push service of the company that makes the browser you turned it on in: Apple for Safari and for FinalFrame added to an iPhone or iPad home screen, Google for Chrome and most other Chromium-based browsers, Microsoft for Edge, and Mozilla for Firefox. We encrypt the message on our server for your browser's keys before it leaves us, so the push service relays a sealed envelope it cannot read; it can still see that FinalFrame sent a message to that browser, and when. Because the notification can appear on your lock screen, its text is generic: one of the two lines above and a link that opens the project, never the photo, its title, a score or your name.
Quiet when you are already looking. If the critique finishes while you have FinalFrame open in front of you, we note that on our side and do not send the notification for it. That note is a timestamp on the notification record and nothing more.
The home-screen app. You can add FinalFrame to your phone's home screen; on iPhone this is the only way to receive notifications. The icon opens an address ending in ?source=pwa, which is the same for everyone (Section 9.1). If you have accepted analytics cookies, we record a launch from the icon, whether our server sees that address or the app notices it is running from the home screen: the date and the device class, linked to your account, at most one entry per device class per day. Separately, and again only if you have accepted analytics cookies, when you open the dashboard, start a critique or open the home-screen app on a phone or tablet running iOS or Android, we note the date and which of the two it runs, at most once a day, working it out from the browser identification (user agent) your browser sends with every request; on any other system we note nothing. We use both to measure whether FinalFrame is used as an installed app, and the launch entries also to stop showing you the iPhone how-to once you have opened FinalFrame from your home screen. We share neither with anyone, and neither follows you to other sites. We delete each launch entry after 90 days; the phone-use time is replaced the next time you use FinalFrame on that kind of device and deleted after 90 days without use, when you withdraw your consent (below) or with your account.
Lawful basis. Sending the notifications you turned on, and keeping the subscription, the note described above and the sign-out record described below that make them work, is part of our contract with you (Art. 6(1)(b)). The launch entries and the phone-use time rest on your consent to analytics (Art. 6(1)(a)), which you can withdraw at any time through “Manage cookie preferences”. Withdrawing stops anything new being recorded from that browser and, if you withdraw through the banner or “Manage cookie preferences” while signed in, deletes the launch entries and the phone-use time we hold for your account; if you withdrew while signed out or by clearing your browser's cookies, email us and we delete them (Section 8).
Turning it off. Account → Notifications → “Notifications on this device” removes that device's subscription. Your browser's site settings for finalframe.photo do the same from its side. If you block notifications there, we never show the browser's permission request again on that device; in FinalFrame added to a phone's home screen, a notice may say where to allow them, a few times at most. If you leave a device without signing out and your session ends on its own, that device keeps receiving these notifications until they are turned off on it or someone else turns them on there; to have it removed without the device, email us (Section 8).
Signing out and back in. Signing out from the menu stops notifications to that device. We delete its subscription and keep one small record with your account: a one-way code made from the delivery address, which cannot be used to send anything, and the time you signed out. While we hold that record, signing in to the same account in that browser turns notifications back on without asking you again, as long as the browser still holds its subscription and its own note of the sign-out (Section 9.1), and still allows notifications. A different account signing in there gets nothing from it. We delete the record when notifications come back on, when someone else turns notifications on in that browser, and in any case after 90 days; after that you can turn them on again from Account. To stop them on a device for good, turn them off there before you sign out; to have the record removed afterwards, email us (Section 8).
3. How We Use Your Data
We use the data described above for the following purposes:
- Providing the service: processing your images through AI critique, generating scores and feedback, enabling iteration comparisons, and running curation sessions
- Account management: authenticating you, managing your subscription, enforcing plan limits and credit balances
- Content safety: screening uploads for prohibited content (violence, self-harm, sexual content involving minors) to keep the platform safe
- AI-generated detection: analyzing uploaded images (with the absence of camera metadata as one contributing signal) to assess whether an image appears to be AI-generated rather than camera-captured, so we can provide appropriate critique context. This detection is automated and best-effort, and may not identify every AI-generated image
- Public gallery: displaying your published work to other users (only when you opt in), showing your photographer page unless you hide it, and showing your display name as the author on share links you create
- Progress tracking: analyzing your critique history to generate personalized coaching insights and identify improvement patterns
- Referral program: matching referral codes, preventing abuse, and awarding credits
- Billing: processing payments, managing subscriptions, and issuing credit packs through Paddle (our Merchant of Record)
- Error monitoring: diagnosing bugs and service issues through Sentry (with your consent for session replay and browser tracing)
- Analytics: understanding usage patterns to improve the product through Vercel Analytics and SpeedInsights (with your consent)
- Upgrade question: asking a Free account that has used all of its credits, once, why it is not upgrading today, and counting the answers (Section 2.13d; not shared)
- Installed-app measurement: recording on which days the home-screen app is opened and when FinalFrame was last used on a phone or tablet, both only with your analytics consent, to decide whether to build a native app (Section 2.20; not shared)
- Communication: responding to your support requests, feedback submissions, and sending transactional notifications (critique ready, iteration ready, curation ready), including notifications on the devices where you turn them on (Section 2.20), and optional engagement emails you can control via your email preferences
We do not use your images to train AI models. Your photographs are sent to the OpenAI API solely for real-time critique. Under OpenAI's API data usage policy, API inputs and outputs are not used to train their models.
We do not sell your personal data. We do not share your data with third parties for their own marketing purposes.
4. Lawful Basis for Processing (GDPR)
If you are in the European Economic Area, the United Kingdom, or another jurisdiction where lawful basis is required, we rely on the following legal grounds:
- Performance of a contract (Art. 6(1)(b)): processing your images, delivering critiques, sending the notifications you turn on for a device (Section 2.20), managing your account, enforcing plan limits, and processing payments. These are necessary to provide the service you signed up for.
- Consent (Art. 6(1)(a)): Vercel Analytics, Vercel SpeedInsights, Sentry Session Replay, Sentry Browser Tracing, PostHog client-side analytics, the home-screen launch record and the phone-use time (Section 2.20), and the first-touch campaign cookies (
ff_utm_source,ff_utm_medium,ff_utm_campaign; Section 9.2) are only activated after you accept the cookie consent banner. You can withdraw consent at any time by rejecting cookies through the banner or the “Manage cookie preferences” option, or by clearing your browser's cookies and site data. - Legitimate interests (Art. 6(1)(f)): core error monitoring through Sentry (crash reports and server-side error tracking, without session replay), server-side product analytics event logging through PostHog (without cookies or device fingerprinting), fraud prevention in the referral program, content moderation to maintain platform safety, naming you as the author on share links you create, asking a Free account that has used all of its credits why it is not upgrading and counting the answers (Section 2.13d), and keeping the cancellation and withdrawal declarations submitted through our no-sign-in pages as evidence that they reached us and what we did with them (Section 7.4). Our legitimate interest is maintaining a functional, safe, and abuse-resistant service, crediting your work to you where you choose to share it, and deciding what to build from how the service is actually used.
- Legal obligation (Art. 6(1)(c)): retaining transaction records as required by tax and financial regulations. We may cooperate with law enforcement authorities upon lawful request regarding content flagged by our moderation system.
5. Third-Party Sub-Processors
Your data is shared with the following service providers, each for a specific purpose. We have data processing agreements in place where required.
- Supabase (San Francisco, CA, USA): Authentication and PostgreSQL database hosting. Supabase stores your account data and critique data; the uploaded image files themselves are held in Cloudflare R2 (see below). Infrastructure runs on AWS.
- OpenAI (San Francisco, CA, USA): Image analysis and critique generation via OpenAI's GPT-5-family vision models. Your images and EXIF metadata are sent for real-time analysis. OpenAI also provides content moderation via the omni-moderation endpoint. Per OpenAI's API data policy, API inputs are not used for model training.
- Paddle: Merchant of Record for all subscriptions and credit pack purchases. Paddle contracts through more than one legal entity, and which one is your counterparty, and therefore which jurisdiction processes your payment data, is determined by the location you purchase from. The current entities and their registered offices are listed in Paddle's buyer terms, linked from Terms Section 11.5. Paddle processes payments, collects and remits taxes (VAT, sales tax, GST), and issues invoices to customers on our behalf. Paddle receives your email and payment information directly. What we keep on our side is described in Sections 2.7 and 7.4a.
- Vercel (San Francisco, CA, USA): Application hosting and deployment. Vercel Analytics and SpeedInsights collect anonymized page view and performance data (only with your consent). Vercel processes HTTP requests, which include your IP address, in the course of serving the application, and keeps its logs of those requests, which record your IP address, for up to 30 days. On some pages Vercel also makes resized copies of your images and keeps them in its cache, as Section 2.10 describes.
- Sentry (San Francisco, CA, USA): Error monitoring and crash reporting. Server-side: collects error events only (no performance-transaction sampling). Client-side: core error monitoring runs by default; Session Replay (with all text masked and all media blocked) and Browser Tracing are only enabled after you consent. Sentry is only active in production. Sentry keeps error reports, including any server-log lines attached to them, and session replays for up to 90 days, and performance traces for up to 30 days.
- PostHog (Frankfurt, Germany (EU Cloud)): Product analytics and event tracking. Collects usage events (e.g., feature usage, conversion funnels) to help us understand how photographers use FinalFrame and improve the product. These events are pseudonymous, not anonymous: once you are signed in they are linked to your user ID, so they remain personal data under Art. 4(5) GDPR and the rights described below apply to them. Client-side tracking (which uses cookies for session identification) is only activated with your consent. Server-side events carry functional event properties and are identified by your user ID or, for the free demo and referral-link events listed in Section 2.15a, by a daily-changing hash of your IP address (no cookies, no device fingerprinting).
- Browser push services (Apple, Google, Microsoft, Mozilla): only if you turn on notifications on a device (Section 2.20). The push service of that browser (Apple Push Notification service for Safari and for home-screen apps on iPhone and iPad; Firebase Cloud Messaging for Chrome and most other Chromium-based browsers; Windows Push Notification Services for Edge; Mozilla's push service for Firefox) delivers an end-to-end-encrypted message it cannot read, addressed to the subscription your browser created with it. We send it nothing else about you; it can see that a message from FinalFrame reached that browser, and when. These services are not our processors: your browser's maker chose which one your browser uses and runs it under its own terms with you, so we have no contract with them. They may handle the delivery in the United States (Section 6).
- Discord (San Francisco, CA, USA): Operational alerting. Receives real-time system-health and service-incident notifications (performance thresholds, background-job health, support-response SLA digests) so we can monitor and maintain the service. Alert payloads are operational and primarily aggregate; where an alert references a specific event for incident correlation it carries only a technical reference and, in some infrastructure alerts, a request IP address: never your images, critiques, or account profile.
- Resend (San Francisco, CA, USA): Transactional and lifecycle email delivery (account, billing, critique-ready, and moderation notices). Resend receives your email address and the content of the messages we send you, including your display name, and the content of the internal summaries we email to ourselves, such as the daily critique-rating summary described in Section 2.13b. Transactional email is sent under our contract with you; marketing email respects your preferences.
- Google Cloud EMEA Limited (Dublin, Ireland): Google Workspace, which hosts our company mailbox, including support@finalframe.photo. Email you send there, for example support requests, appeals, requests under Section 8, and withdrawal or cancellation declarations, is stored in it together with our replies, and so is the daily critique-rating summary described in Section 2.13b. Our daily internal moderation summary is stored there too: it counts the moderation actions described in Section 2.6 and lists the email address and account ID of accounts blocked that day, and of certain accounts blocked more than seven days earlier for which no review request has been recorded, each listed again daily until its block is resolved. Google therefore receives your email address, the content of those messages and any attachment you include, and what those summaries record. Google may process this data outside the EEA, in the United States and in the other countries named in Google's published list of Google Workspace subprocessors, under the safeguards described in Section 6.
- Upstash, Inc. (USA): Rate-limiting infrastructure (Redis) that protects our site, including our AI endpoints, from abuse. To enforce per-user and per-IP limits, Upstash receives your IP address and, for signed-in requests or a cancellation or withdrawal declaration that matches your account, your user ID as rate-limit keys. To limit how often one email address can be used or written to, it also receives, as a rate-limit key, a hash of an email address typed into the cancellation or withdrawal page (Section 2.13c), of a contact email saved on a profile (Section 2.19), and of the address given at sign-up when an earlier sign-up with that address was never confirmed. Such an address may belong to someone other than the person who typed it. Every one of these keys, whether an IP address, a user ID or an email-address hash, expires automatically within about two days of being set. It does not receive your images, critiques, or account profile.
- Cloudflare, Inc. (San Francisco, CA, USA): Cloudflare, Inc. (USA): protezione anti-bot (Turnstile) alla registrazione (elabora indirizzo IP, caratteristiche del browser/TLS e segnali di interazione per il rilevamento degli abusi), e l'archiviazione di oggetti di Cloudflare R2, che conserva le tue immagini caricate, i tuoi avatar e i tuoi screenshot di feedback; trasferimenti coperti da Clausole Contrattuali Standard.
6. International Data Transfers
FinalFrame is operated by Crypto Brains DOO from Serbia. Most of our sub-processors listed above are US-based companies. If you are accessing the service from within the EEA or UK, your data will be transferred to and processed in the United States and Serbia.
For transfers from the EEA/UK, we rely on:
- Standard Contractual Clauses (SCCs) incorporated into our agreements with sub-processors where applicable
- The EU-U.S. Data Privacy Framework, where the recipient (a sub-processor, or a browser push service described in Section 5) is a certified participant
- For a browser push service that is not a certified participant, the delivery happens only because you asked for notifications in a browser that uses it (GDPR Art. 49(1)(b))
If you have concerns about international data transfers, please contact us at support@finalframe.photo.
7. Data Retention
Retention periods depend on your plan:
7.1 Free Plan
- 90-day active window. On the Free plan, individual projects older than 90 days are “archived”: frozen and no longer editable or viewable in full, but not permanently deleted. This applies per project by its age, so your account and newer projects remain fully accessible. Your data (images, critiques, and account information) is retained; if you upgrade to a paid plan, archived projects become accessible again, and all data persists until you delete your account.
7.2 Pro Plan ($19/month) and Premium Plan ($36/month)
- Unlimited retention for as long as your subscription is active. If your subscription ends and you revert to the Free plan, the 90-day freeze policy applies going forward.
7.3 Purchased Credit Packs
- Credit expiry. Purchased credits expire 12 months after your most recent credit pack purchase. Each new purchase resets the expiry window for all your purchased credits. Your expiry date is shown on your account page and on your dashboard, so you can see it before it arrives.
7.4 Account Deletion
- You can delete your account from Account Settings, or by emailing support@finalframe.photo if you cannot reach that setting, which is the case while an account is suspended and for accounts that sign in only through Google and so have no password to confirm with. When you do, we perform a cascade deletion across our database, with the limited exceptions set out in this section. The categories of data removed include your profile, all projects, all image versions (including any short-term restore snapshots from the per-version delete/undo feature), all critiques and iteration comparisons, all curation sessions, all comparison records, all usage events, all bookmarks and likes, all tags, all progress insights, all coaching brief history, all challenge entries, all feedback submissions, all referral records, all notification preferences, device notification subscriptions, home-screen launch records, the upgrade-question record (Section 2.13d) and email-event records, and all share tokens are permanently removed from our database.
- All stored image files (photographs, avatars, feedback screenshots) are deleted from cloud storage.
- Resized copies of your images in our hosting provider’s image cache are not removed by this step; Section 2.10 explains how long they stay current and why we cannot give an end time after that.
- Your authentication record is deleted from Supabase Auth.
- Copies in our database provider's backups expire within 10 days.
- What we retain after deletion: if any of your uploads were flagged by our content moderation system (Section 2.6), the moderation event metadata (image hash, flagged categories, timestamp, IP address, and user agent) is retained with your user ID removed. This record is pseudonymous rather than anonymous: your account no longer links to it, but it keeps those technical identifiers alongside a one-way hash of your email address, so we can re-link it to you if a law enforcement request or a data protection inquiry names you. It is kept for platform safety and potential law enforcement cooperation under our legitimate interest (Art. 6(1)(f) GDPR). Similar minimal-metadata retention applies to consent records (cookie + email consent audit trail) for up to 6 years from the consent event (aligned with GDPR Art. 7(1) demonstrability and German HGB § 257 commercial record-keeping where applicable), non-billing administrative audit logs of moderation actions, suspension reinstatements, and withdrawal-waiver decisions affecting your account (36 months from the action; billing-related admin actions are retained for 10 years under Section 7.4a), and username tombstones (reserved-username records purged within 90 days). In each case, personal identifiers are dissociated (your user ID is set to null) while the operational record persists for compliance, audit, and anti-impersonation purposes.
- Anti-abuse email hash: after you delete your account, we keep a one-way keyed cryptographic hash (HMAC-SHA256, computed with a separate server-side secret key) of your email address solely to prevent repeated free-credit sign-ups. The hash contains no readable personal data, cannot be turned back into your address, and cannot be tested against a list of guessed addresses without the key. It is used only to decline promotional bonus credits if the same email signs up again. Your account still works normally on a future sign-up; only the one-time bonus credits are withheld. Lawful basis: legitimate interest (GDPR Art. 6(1)(f)) in fraud and abuse prevention; this minimal record does not override your rights because it is read only at sign-up to decide one promotional grant, it is never used to contact you, and it holds no readable personal data. Retention: the hash is kept for as long as the abuse-prevention purpose subsists.
- Subscription event ledger (paused/resumed events): retained 10 years under Serbian bookkeeping and tax rules (Law on Accounting Art. 28; Law on Tax Procedure and Tax Administration Art. 114): see Section 7.4a. Personal identifiers are SET NULL on account deletion (migration 0158 pattern) while preserving the billing audit trail.
- Failed payment notifications: an entry in the log of payment notifications we could not process (Section 7.4a) is not stored against your account, so deleting your account does not remove it. It keeps your customer ID at the payment provider, the amounts involved and the error we encountered until it is purged on the schedule in Section 7.4a, and the full copy of the notification it holds is deleted once the entry is 90 days old. Lawful basis: our legitimate interest (GDPR Art. 6(1)(f)) in correcting a payment that did not reach your account as it should have.
- Support correspondence (billing, appeals, and data-protection requests): messages you send us through the in-app feedback form in the billing, appeal, or data-request categories, or by email to support@finalframe.photo, and our replies, are retained as evidence of the request and our response in case of a later dispute or regulatory inquiry, even after your account is deleted. Lawful basis: our legitimate interest (GDPR Art. 6(1)(f)) in defending and substantiating our handling of your requests (Art. 17(3)(e)), and, for consumer complaints, our statutory record-keeping obligation under Article 55(6) of the Serbian Law on Consumer Protection (Official Gazette RS 88/2021; from August 2026, Article 63(6) of Official Gazette RS 35/2026), which requires keeping a record of received complaints for at least two years. Retention: up to 36 months, after which these records are permanently erased. When your account is deleted, in-app records are dissociated from your identity: the link to your profile is removed and attached screenshots are deleted; the message text itself is retained as written, together with a one-way cryptographic hash to correlate the record if a dispute arises. For the consumer-complaint categories, your name is also kept in the complaint record, because the Serbian complaint-record rules (Art. 55(8); from August 2026 Art. 63(8)) require the record to identify the complainant. Other feedback submitted through the form (bug reports, feature ideas, critique-quality ratings) is deleted together with your account.
- Cancellation declarations: if you cancelled through the “Cancel your subscription” page, the declaration you submitted is kept after your account is deleted. Deleting your account removes the link to your profile; the record itself stays, holding the name and email address you typed, the address you asked us to send the confirmation to, your description of the subscription, the date and time we received it, our record of what we did with it (whether it matched a subscription and the date the contract ends), and the IP address and browser identification of the submission. We keep it until the end of the tenth calendar year following the year the contract ended. Only for counting that period, we start from the 63rd day after the contract's end date, or after the day we received the declaration if that is later or we hold no end date for it, and we use the same number of days for every declaration. The reason is that a claim about the record would be about a charge taken after the contract ended: the first such charge can come up to one billing period after we received a declaration we hold no end date for, and up to 30 days later again if the charge first fails and is retried, and we add 2 days so that a time-zone difference, or the claim period starting only the day after, can never cut the record short. That keeps the record for the whole period within which a claim for the return of that first charge can be brought under the law that governs our Terms (Terms Section 21); we then delete it permanently by a scheduled daily job. The IP address and browser identification are removed earlier, at the end of the third calendar year following the year we received it, because their only purpose is to trace a declaration made in someone else's name. Lawful basis: our legitimate interest (GDPR Art. 6(1)(f)) in being able to show that a cancellation reached us and when, which is also what we must be able to confirm under German § 312k BGB. Sending the confirmation itself is a legal obligation (Art. 6(1)(c); § 312k Abs. 4 BGB). Only FinalFrame reads the record; the confirmation and the copy we send to the account's own address go through our email provider (Section 5). Where it matches a subscription we ask Paddle to end that subscription, and nothing else from the declaration is sent to Paddle. That page needs no sign-in, so anyone can submit against any address. If a declaration was filed in your name and you want the record removed sooner, email support@finalframe.photo. Your other rights over the record, including the right to complain to a data protection authority, are in Section 8.
- Withdrawal declarations: if you withdrew from a purchase through the “Withdraw from contract here” page, the declaration you submitted is kept after your account is deleted. Deleting your account removes the link to your profile; the record itself stays, holding the name and email address you typed, the address you asked us to send the acknowledgement to, your description of the purchase, the language the page was in, the date and time we received it, our record of what we did with it (when we acknowledged it, when we told the account holder, whether the account holder objected, when it was processed, and the payment provider's reference for the refund), a snapshot taken at receipt of the credits each affected purchase provided and how many had been used (the basis for the proportional amount under Directive 2011/83/EU Art. 14(3) and Section 11.8 of our Terms), and the IP address and browser identification of the submission. We keep it until the end of the tenth calendar year following the year its refund fell due, and we date that as the sixteenth day after we received it: the refund is due within 14 days, and we add 2 so that a time-zone difference, or the claim period starting only the day after the due date, can never cut the record short. That covers the period within which a claim about the refund can still be brought under the law that governs our Terms (Terms Section 21); we then delete it permanently by a scheduled daily job. The IP address and browser identification are removed earlier, at the end of the third calendar year following the year we received it, because their only purpose is to trace a declaration made in someone else's name. Lawful basis: our legitimate interest (GDPR Art. 6(1)(f)) in being able to show that a withdrawal reached us and when, what we refunded and why that amount, and in establishing or defending a claim about it (Art. 17(3)(e)). Sending the acknowledgement itself is a legal obligation (Art. 6(1)(c); Directive 2011/83/EU Art. 11a(4), German § 356a BGB), discharged when it is sent. Only FinalFrame reads the record; the acknowledgement and the copy we send to the account's own address go through our email provider (Section 5), and nothing from the declaration is sent to Paddle. Your data export (Section 8.1) includes declarations naming your account and any you submitted while signed in; for a declaration that named someone else's address, the processing details are withheld. That page needs no sign-in, so anyone can submit against any address. If a declaration was filed in your name and you want the record removed sooner, email support@finalframe.photo. Your other rights over the record, including the right to complain to a data protection authority, are in Section 8.
- Erasure receipts: when we ask PostHog to delete your analytics person record (Section 2.15a), we keep a receipt of that request for 36 months. It holds no readable personal data: your user ID and the analytics identifiers the request covered are stored only as one-way keyed hashes, alongside PostHog's own opaque record number and whether the request succeeded. We keep it because it is the only evidence that this part of your deletion was carried out (GDPR Art. 5(2) accountability). It is never used to contact you and never used to build a profile.
- What we cannot delete: data already transmitted to third parties. Paddle (our payment processor) retains your transaction history, payment method details, email address, and tax records as required by financial regulations. Sentry retains for up to 90 days: error logs and, if you consented to them, session replays and performance traces, which may include your pseudonymous user ID (a random identifier, never your email or name), the record number PostHog uses for you if deleting your analytics record has to be finished by hand, your Paddle customer, subscription, transaction, event and adjustment (refund, credit or chargeback) IDs where we logged anything concerning your billing (for example an error, a failed payment, a refund, credit or chargeback, or a repeated Paddle notification), the check results described in Section 2.15a or, for the free demo, the daily IP hash. To request deletion of Paddle-held data, contact Paddle directly at privacy@paddle.com. Each provider's own retention policies apply. Session replays are the exception: we delete yours from Sentry before that period ends if you ask us (Section 8).
7.4a Billing Communications and Paddle (Merchant of Record)
Billing is processed by Paddle (“Paddle”) acting as our Merchant of Record. Paddle issues transaction receipts directly to the payment method on file and is responsible for VAT, sales tax, and GST collection and remittance. FinalFrame does not send a separate billing receipt for renewal charges.
Billing records (subscription_events, and the billing-tied rows of admin_audit_log as defined in Section 12.1) are retained for 10 years after the related transaction, in line with the Serbian rules for our billing books and records (Law on Accounting Art. 28: journal and general ledger kept ten years; Law on Tax Procedure and Tax Administration Art. 114: the ten-year absolute tax-limitation period). Paddle, as our Merchant of Record and the issuer of your invoice, is separately subject to its own invoice-retention obligations (including the EU One-Stop-Shop ten-year rule, Art. 369k of the VAT Directive), which attach to Paddle, not to us. This retention is a legal obligation under GDPR Art. 17(3)(b): even if you delete your account, the billing records described above are retained for the full 10-year window, but personal identifiers (your user_id) are dissociated from those rows at deletion time so the rows persist as pseudonymous accounting records. As with the moderation records in Section 7.4, these are pseudonymous rather than anonymous: the row keeps the Paddle transaction, refund and event identifiers alongside a one-way hash of your email address, so we can re-link it to you for finance, audit or chargeback-defence purposes. They therefore remain personal data under Art. 4(5) GDPR, and the rights set out in Section 8.1 apply to them. Because this retention is mandated by law, we cannot delete these rows before the 10-year period ends, even on an Art. 17 erasure request; we will restrict processing on request instead (Art. 18). Administrative audit rows that are not part of the billing record, such as moderation actions, appeal outcomes, reinstatements, regenerating your share tokens, threshold changes, and administrative reads of your data, are not covered by this ten-year obligation: they are retained for 36 months from the action, as set out in Section 12.1. If you delete your account before that period ends, your user ID is set to null on those rows, but the record itself persists until the 36 months elapse, as described in Section 7.4. Your rights over that processing, including the right to object, are set out in Section 8.1. Our billing_webhook_failures log is a separate short-lived operational record used to detect and resolve failed payment-provider webhooks; resolved entries are automatically purged 30 days after they are recorded. An entry that is still unresolved is retained until the underlying payment-provider failure is resolved, and is then purged on that same 30-day schedule: it is not deleted on a timer, because an unresolved payment failure is the record we need in order to correct your billing. Each entry also stores a full copy of the notification the payment provider sent us, so that a failed notification can be processed again once the fault is fixed. For a payment, that copy may include the name on the card, the card brand, its last four digits and its expiry date, or the email address of a PayPal account, but never the full card number or security code. The copy is deleted once the entry is 90 days old, even if the entry is still unresolved; an entry resolved before then is purged together with its copy on the 30-day schedule above. The rest of the entry (the type and reference of the event, your customer ID at the payment provider, the amounts involved, the error we encountered and, once resolved, how it was resolved) is kept for the periods above. It is not a statutory accounting record subject to the 10-year period. Paddle, our Merchant of Record, retains separate billing data under its own retention policy: see Paddle's privacy policy for their specifics.
If your account is paused for a content-moderation review, we suppress our own billing-related communications (including upgrade prompts and plan-change confirmations) to avoid sending conflicting signals while the review is open. Paddle, as the legal seller of your subscription, may continue to send tax documents, receipts, or regulatory notices directly to your payment-method email address. You can request an export of the Paddle-held transaction history at any time by contacting privacy@paddle.com.
7.5 In-App Deletion (Soft Delete)
When you delete individual comparisons or projects within the app, the data is soft-deleted and retained for 30 days to allow recovery in case of accidental deletion. After 30 days, soft-deleted records are permanently purged. Full account deletion (Section 7.4) bypasses the soft-delete period and permanently removes all data immediately.
7.6 Demo Sessions
- Demo session data (for unauthenticated users) includes the IP address, critique data, and demo image. Demo images may be cleaned up on a separate schedule from account data.
- Unclaimed demo sessions and their images are deleted after 30 days. If you create an account and claim a demo critique, its data is migrated to your account and follows your account's retention schedule instead.
7.7 Portfolio Contact Messages
- Records of messages sent through a photographer's contact form (Section 2.19), covering the sender's name, email address, message, IP address, timestamp, and a one-way cryptographic digest of the recipient photographer's contact address (used to limit how many messages any one address can receive per day), are permanently deleted 90 days after submission, by a scheduled daily job. This applies to refused submissions as well as delivered ones.
- Deletion is unconditional and needs no request from you. If you are an anonymous sender and want your record removed sooner, email support@finalframe.photo; we can locate it by the address you used.
- The message that was delivered continues to exist in the recipient photographer's own mailbox, which we do not control. A report does not hold the record back either; it is deleted on the same schedule, and we work from the copy forwarded to support@finalframe.photo.
8. Your Rights
8.1 Rights Under GDPR (EEA/UK Residents)
If you are in the EEA or UK, you have the following rights under GDPR Articles 15–22. Because we are established in Serbia, you have the same rights under Serbia's Law on Personal Data Protection wherever you live:
- Right of access (Art. 15): request a copy of all personal data we hold about you
- Right to rectification (Art. 16): correct inaccurate data (you can update your profile directly in the app)
- Right to erasure (Art. 17): delete your account and all associated data (available in Account Settings, or by emailing support@finalframe.photo, which is the route to use if your account is suspended, or if you sign in only through Google and so have no password to confirm with)
- Right to restriction (Art. 18): request that we limit processing of your data in certain circumstances
- Right to data portability (Art. 20): download your data instantly in JSON format from Account Settings, or email support@finalframe.photo for manual assistance
- Right to object (Art. 21): object to processing based on legitimate interests
- Right not to be subject to automated decision-making (Art. 22): our AI critique is informational and educational, not a binding automated decision that produces legal effects. However, if you believe an automated moderation decision (content blocking) was made in error, you can contact us for human review.
To exercise any of these rights, email us at support@finalframe.photo. We will respond within 30 days.
You also have the right to lodge a complaint with your local data protection supervisory authority, or with the Serbian Commissioner for Information of Public Importance and Personal Data Protection (Poverenik), which supervises us as a company established in Serbia.
8.2 Rights Under CCPA/CPRA (California Residents)
If you are a California resident, you have the right to:
- Know what personal information we collect, use, and disclose
- Delete your personal information
- Opt out of the sale or sharing of your personal information; we do not sell or share your personal information as defined under the CCPA/CPRA
- Non-discrimination: we will not discriminate against you for exercising your rights
To exercise these rights, email us at support@finalframe.photo or use the account deletion feature in Account Settings.
9. Cookies and Tracking Technologies
FinalFrame takes a consent-first approach to tracking:
9.1 Essential (Always Active)
- Supabase Auth session cookies/storage: required to keep you logged in. These are strictly necessary for the service to function.
- Consent preference: stored in your browser's localStorage (key:
ff-consent) to remember whether you accepted or rejected analytics cookies, and mirrored in theff_consentcookie below. ff_consentcookie: stores the same accept or reject choice (“accepted” or “rejected”) in a form our servers can read, so the campaign cookies described in Section 9.2 are set only after you accept. This is a strictly necessary functional cookie (Secure, 1-year expiry) that records the choice you made. It is removed if you reset your cookie preferences. No consent is required.- Record of your choice on our servers: each time you accept, reject or reset this choice, our servers also record it, with the time, your browser's user agent and, for an accept or reject, the language and wording of the banner you were shown; if you are signed in, the record also holds your account and the IP address you used. We keep it to show what you were asked and what you answered, which GDPR Art. 7(1) requires us to be able to do (legal basis: Art. 6(1)(c)). A record made while you were not signed in does not include your IP address and is deleted 6 years after the choice; a record tied to your account is kept while the account exists, loses your account and IP address when the account is deleted, and is deleted 6 years after the choice (Section 7.4).
- Sentry core error monitoring: server-side error tracking and basic client-side crash reporting run without consent, as they are necessary for maintaining service reliability. No session replay or detailed browser tracing is included.
NEXT_LOCALEcookie: stores your language preference so the site displays in your chosen language. This is a strictly necessary functional cookie (Secure, 1-year expiry). No consent is required.ff_refcookie: stores a referral code when you arrive via a referral link or open a shared link that carries a referral code, so the referral can be attributed when you sign up. This is a short-lived functional cookie (httpOnly, Secure, 30-day expiry) that is consumed and cleared at signup. No consent is required.demo_tokencookie: set when you run a demo critique without an account. It links a demo critique you ran before signing up to your new account so your result appears in your dashboard. This is a strictly necessary functional cookie (httpOnly, Secure, 30-day expiry) under ePrivacy Art. 5(3) (service you explicitly requested) and GDPR Art. 6(1)(b). No consent is required.ff_mkt_optoutcookie: set only when you decline marketing emails while signing up, on the step that confirms your sign-up. It holds your account id so that refusal reaches your new account's email preferences even if the sign-in service could not record it. It has no further effect once your account has been created, and it expires after one hour. This is a strictly necessary functional cookie (httpOnly, 1-hour expiry) that carries an objection you made (GDPR Art. 21). We hold your account id in it because the law obliges us to honour that objection (GDPR Art. 6(1)(c)). No consent is required.ff:pending_upgrade_celebrationcookie: set when you start a subscription checkout or change plan. It holds only the plan name (Pro or Premium), so the page you return to after payment can confirm the upgrade once. It is cleared when you return from payment and otherwise expires after 15 minutes. This is a strictly necessary functional cookie (15-minute expiry) for the purchase you requested. No consent is required.- Interface memory (localStorage): small entries that remember what you did in the interface on that device, such as a banner or prompt you dismissed, a “Not now” on the notification offer and when it may appear again, what you have already seen, and your last-used settings, and a short code derived from the signed-in account, used only to clear these entries when a different account signs in on that device. For the notification offer we also count the critiques started on that device, so it is not shown on your first one; the notification-offer entries never leave your browser. They are removed when you clear this site's data. No consent is required.
- Unsaved profile edits (sessionStorage): while you edit your profile, the fields you have changed but not yet saved (for example your bio or contact email) are kept in the sessionStorage of the browser tab you are editing in, under a key that includes your account ID (
ff:profile-draft:followed by the ID). Each change is stored with the saved value it replaces, so a version saved since from another tab or device takes precedence. If you leave the page and come back to it in that tab, your changes are put back in the form, still unsaved. The entry never leaves your browser, and it is removed when you save, when you change the fields back to their saved values, when you sign out or delete your account in that tab, and when the tab’s browsing session ends, which is normally when you close the tab (if your browser reopens closed tabs or restores your last session, the entry can come back with the tab). We receive your changes only when your profile is saved. This storage is strictly necessary for the edit you are making, so no consent is required. - Notifications and the home-screen app: only if you ask for them. Turning on notifications registers our service worker (a small script that only shows notifications and stores no pages or data) and the subscription described in Section 2.20; turning them off removes the subscription. Signing out from the menu leaves both in your browser. If notifications were on for your account there, it also leaves a small localStorage entry (
ff_push_parked) holding only the day of that sign-out; it names no account. While that entry is there, a signed-in visit asks our server whether the account holds any sign-out record (Section 2.20), and only on a yes do we read the browser's subscription and check it against that account's records. The entry has no expiry of its own: FinalFrame removes it when notifications come back on, when anyone turns notifications on or off in FinalFrame in that browser, and the first time someone is signed in there more than 90 days after the sign-out; clearing this site's data removes it too. Adding FinalFrame to your home screen stores our app description on your device, including the address its icon opens,/dashboard?source=pwa. That address is the same for everyone and identifies no one; our server reads it to count a launch from the icon only if you have accepted analytics cookies (Section 2.20). __cf_bm / cf_clearance: Cookie di sicurezza strettamente necessari impostati da Cloudflare Turnstile; esenti da consenso ai sensi dell'Art. 5(3) della Direttiva ePrivacy; non utilizzati per analisi o tracciamento.
9.2 Analytics and Performance (Consent Required)
The following are only activated after you click “Accept” on the cookie consent banner:
- Vercel Analytics: collects anonymized page view data to help us understand which features are used
- Vercel SpeedInsights: collects page load performance metrics (Core Web Vitals) to help us optimize speed
- Sentry Session Replay: records session replays to help us diagnose bugs. All text is masked and all media (including your photographs) is blocked in replays. The replay is pseudonymous rather than anonymous: it is tied to your user ID, so it remains personal data under Art. 4(5) GDPR.
- Sentry Browser Tracing: collects performance traces for client-side transactions
- PostHog product analytics: captures product-usage events (EU-hosted) to help us understand how features are used. Once you are signed in these are linked to your user ID, which makes them pseudonymous rather than anonymous
ff_utm_source,ff_utm_mediumandff_utm_campaigncookies: record the campaign parameters of the first campaign link you arrive through after you accept (first-touch campaign attribution); a link you followed before accepting is not recorded. They are never overwritten by a later link, and expire after 30 days (httpOnly, Secure). They are removed on your next visit after you reject or reset your cookie preferences. If you sign up while they are present and your choice is still “accepted”, their values are stored with your account as the acquisition fields described in Section 2.15a.
If you click “Reject,” none of the consent-gated technologies are activated. You can change your preference at any time using the “Manage cookie preferences” option in the page footer or in your account settings.
Withdrawing your consent (“Reject”, or “Manage cookie preferences”) takes effect at once, without reloading the page: the technologies above stop collecting, and PostHog's identifier (the ph_ff_ph cookie, which otherwise expires a year after it was last refreshed, and the localStorage entry of the same name, which has no expiry of its own) is removed from your browser. PostHog keeps a small marker in localStorage recording only that you opted out. Withdrawal does not affect the lawfulness of what was collected before it. Product-usage events your browser recorded before you withdrew but had not yet sent can still reach PostHog afterwards: normally within a few seconds, or later while the page stays open if an earlier attempt to send them failed. Data already sent is kept for the periods in Sections 2.15a, 5 and 7 and then deleted; to have your PostHog events or Sentry session replays deleted sooner, contact us (Section 8).
10. Children's Data
FinalFrame is not intended for use by anyone under the age of 16. We do not knowingly collect personal data from children. If you believe a child under 16 has created an account, please contact us at support@finalframe.photo and we will promptly delete the account and all associated data.
11. Biometric Data
Photographs you upload may contain images of people. We want to be clear about what our AI does and does not do:
- FinalFrame does not perform facial recognition.
- FinalFrame does not extract biometric identifiers (faceprints, iris scans, voiceprints, or similar).
- FinalFrame does not attempt to identify individuals in your photographs.
Our AI analyzes photographs for composition, lighting, color, technical quality, and artistic merit. When people appear in photographs, the AI may assess compositional elements (e.g., subject placement, posing, expression as it relates to mood) but does not perform any biometric measurement or identification.
This distinction matters under laws like the Illinois Biometric Information Privacy Act (BIPA), the Texas Capture or Use of Biometric Identifier Act (CUBI), and similar state laws. Since we do not collect, capture, or store biometric identifiers or biometric information, these laws do not apply to FinalFrame's image analysis.
12. Security Measures
We take the following measures to protect your data:
- Encryption in transit: all data transmitted between your browser and our servers uses TLS/HTTPS
- Encryption at rest: our database (Supabase/AWS) and object-storage provider (Cloudflare R2) encrypt data at rest
- Signed URLs: images in storage are not publicly accessible. They are served through time-limited signed URLs (up to 3 hours for gallery and share images, up to 3 hours for your profile photo and cover photo wherever they appear, up to 1 hour for other images on your own account pages, and up to 7 days for a thumbnail embedded in an email we send you). A resized copy made from one of these URLs can stay reachable after the URL expires, as Section 2.10 explains
- Image validation: uploaded files are validated at the byte level (magic bytes verification) to prevent disguised malicious files
- GPS stripping: location data is actively removed from all stored image copies through re-encoding
- Authentication scoping: all data mutations verify the authenticated user ID, preventing cross-account access
- Cascade deletion: account deletion cascades through all related data via foreign key constraints, ensuring no orphaned data remains
- Content moderation: all uploads are screened before processing to prevent illegal content from being stored
- Active subscription check on deletion: account deletion requires canceling any active subscription first, preventing accidental data loss
- Administrative access: authorized FinalFrame administrators may access user account data, usage statistics, and critique history for customer support, abuse investigation, and service operations. Every administrative read of personal data and every administrative mutation (including viewing a user's details, granting credits, adjusting plans, regenerating share tokens, and reviewing or resolving moderation appeals) is recorded in an append-only audit log under GDPR Art. 30(1)(d). See Section 12.1 below for the audit-trail scope, retention, and administrator authentication controls.
No system is perfectly secure. If you discover a security vulnerability, please report it responsibly to support@finalframe.photo.
12.1 Administrative Access and Audit Trail
Where administrative access is exercised, the following controls apply:
- Audit-trail granularity: an append-only row is written to our
admin_audit_logtable for every read of personal data (such as opening a user's details page or downloading a feedback screenshot) and every mutation (such as granting credits, changing a plan, regenerating share tokens, resolving appeals, or updating moderation thresholds). Each row records the administrator's identifier, the action name, the target user identifier where applicable, a JSON payload describing the change before and after, and the timestamp. - Retention period: non-billing administrative actions are retained for 36 months from the date of the action under the GDPR Art. 5(1)(e) storage-limitation principle. Administrative actions that form part of the billing record (credit grants, refund logs, plan changes that affect invoicing) are retained for 10 years in line with the Serbian rules for our billing books and records (Law on Accounting Art. 28; Law on Tax Procedure and Tax Administration Art. 114). Paddle, as our Merchant of Record, is separately subject to the EU One-Stop-Shop ten-year invoice-retention rule (Art. 369k of the VAT Directive). The 10-year retention overrides the 36-month default for billing-tied actions only.
- Administrator authentication: FinalFrame administrators are subject to mandatory time-based one-time password (TOTP) second-factor authentication in addition to email-and-password sign-in. Administrative actions cannot be performed until a verified TOTP factor is enrolled. See our Terms of Service §11.13 (Administrator Access) for the full description of administrator authentication and account-reinstatement controls.
- Administrator identification under self-erasure: if an administrator exercises their own GDPR Art. 17 right to erasure, the administrator identifier on prior audit rows is set to NULL but the action name, target, payload, and a one-way hash of the administrator's email are retained for the applicable retention period above. This preserves the audit trail required by Art. 30(1)(d) without retaining the now-deleted personal data.
- Automated decisions taken by administrators: where an administrator changes a moderation threshold (the score above which uploads are automatically blocked or flagged), the rationale entered by the administrator is recorded in the audit row alongside the before/after values as required by Article 14 of the EU Artificial Intelligence Act (human oversight of automated decisions).
Our internal Data Protection Impact Assessment (DPIA), referenced in Section 2.15, contains the underlying analysis for these controls (DPIA §1.4 administrative-access scope and §3.5 moderation-threshold authority).
12.2 Personal Data Breach Notification
Despite the safeguards above, no system is immune to security incidents. If we become aware of a personal data breach (the accidental or unlawful destruction, loss, alteration, unauthorized disclosure of, or access to your personal data), we will respond in accordance with our internal incident-response procedure as follows:
- Notification of the supervisory authority (GDPR Art. 33): we will notify the competent supervisory authority (the Serbian Commissioner for Information of Public Importance and Personal Data Protection, and your local EEA/UK supervisory authority where applicable) without undue delay and, where feasible, no later than 72 hours after becoming aware of the breach, unless the breach is unlikely to result in a risk to your rights and freedoms.
- Notification of affected users (GDPR Art. 34): where a breach is likely to result in a high risk to your rights and freedoms, we will notify you directly and without undue delay, in clear and plain language. That notice will describe the nature of the breach, its likely consequences, the measures we have taken or propose to take to address it, and a point of contact from whom you can obtain more information.
The detection, assessment, containment, and reporting workflow that governs this commitment is documented in our internal Data Protection Impact Assessment (DPIA §4.3).
13. Changes to This Policy
We may update this privacy policy from time to time to reflect changes in our practices, our sub-processors, or applicable law. When we make material changes, we will:
- Update the “Last updated” date at the top of this page
- Notify registered users by email for significant changes that affect how your data is processed
- Post a notice within the application for changes that affect active features
We encourage you to review this policy periodically. Your continued use of FinalFrame after changes take effect constitutes acceptance of the updated policy.
14. Contact Us
For any questions, concerns, or requests related to this privacy policy or your personal data, please contact:
- Company: Crypto Brains DOO
- Address: Jove Kursule 9, Šabac 15000, Serbia
- Email: support@finalframe.photo
We aim to respond to all privacy-related inquiries within 30 days.
This privacy policy was drafted for attorney review and is not a substitute for formal legal advice. If you have specific legal concerns, we recommend consulting a qualified attorney in your jurisdiction.