Knotty Games
Privacy Policy
Last updated October 27, 2026
This policy describes what the Knotty website actually stores and who receives it. It is written from the product as it is built. Where a retention period or a vendor setting is not recorded in this repository, the policy says what the vendor publishes and what this repository does not confirm.
Who we are
Atlas Holding Group LLC operates Knotty Games at knotty.games. Visits to kinky.games are redirected to knotty.games. The app runs on Cloudflare Workers. Account, profile, room, suggestion, and inbound-mail records are stored in a Cloudflare D1 database named in the project configuration.
Mailing address: 734 Bellevue Ave E, Seattle, WA 98102. Email hello@knotty.games. Mail sent to @knotty.games is received by a Cloudflare email worker, stored in that database, and shown on an operator admin page.
The Worker configuration does not set a D1 location hint or a jurisdiction. Cloudflare’s documentation says that, without those, D1 creates the primary database in a location close to where the database was created. That location is not recorded in this repository, so this policy does not name a region.
Workers Logs are turned on for the site Worker and the inbound-mail Worker. The configuration enables observability and does not set a retention period or a sampling rate. Cloudflare’s default is to log every invocation. Cloudflare’s Workers Logs documentation keeps those logs for 3 days on the Workers Free plan and 7 days on the Workers Paid plan, and 7 days is the published maximum. This repository does not record which plan the account is on, so the period that applies is one of those two.
18+ only
Knotty is only for people 18 or older. Before the site is usable, it asks you to confirm that you are at least 18 (or the age of majority where you live, if that is higher) and that viewing adult content is legal for you. That confirmation is saved in this browser’s local storage. It is not a cookie, it has no expiry in the code, and it stays until you clear site data for knotty.games. It does not prove your age.
Creating an account requires a checkbox that you are 18 or older. The server refuses to create the account if that value is not true. An optional birthdate on your profile is stored if you enter one. If that date calculates to under 18, the operators are emailed the account email, the username, and the birthdate so they can review it. Saving the date is not blocked automatically, and the account is not deleted automatically.
Information you give us
Account. If you sign up, we store an email address, a username, and a display name. The username and display name are derived from the part of your email before the @, with a number added so the username is unique, so a piece of the email can show up in the username. We also store whether you confirmed you are 18 or older, whether the email has been verified, and the times the account was created and updated. The account table has a column for an image. The sign-up form does not ask for a photo, and this app does not set one.
The password is stored as a scrypt hash through Better Auth 1.7.7, the authentication library this site uses. We do not store the password you typed. Sign-up sends a confirmation email, but you can use the account before you confirm it. A password-reset link expires after one hour. That lifetime is set in our auth config. The confirmation-link lifetime is Better Auth’s default of one hour, because this project does not set a different one.
Profile, if you fill one in. The profile can include your name, a partner’s name, whether you are playing as a couple or solo, gender, body, foreskin status, a partner’s gender and body, a lead/follow/switch role, a heat level, themes you love, themes that are off limits, themes you have unlocked, free-text turn-ons, an optional birthdate, optional size measurements, and the latest yes/no/maybe overlap. It is saved in this browser. If you are signed in, it is also copied to your account in the database. When you sign in, the account copy replaces the browser copy, unless the account has none, in which case the browser copy is uploaded. Signing out clears the copy in that browser.
Other players do not receive your limits or your partner’s private yes/no/maybe answers. A shared yes/no/maybe room shows the overlap only after both of you lock answers. Operators can read profiles in the database. An admin screen shows recent turn-on text, birthdates on the user list, and aggregate counts (for example theme totals and median size). Those aggregates are not a public profile.
Shared game rooms. Games on one phone keep their cards in the browser. When you play on two phones, or in a circle, the room is a row in the database: a code, the game, the host account, the guest account if there is one, and a JSON state. That state can include names, gender, body, limits, cards in play, scores, yes/no/maybe answers, and who joined a circle. Each move sets the room to expire 24 hours later. An expired room is deleted when someone opens that room code, and every expired room is deleted when anyone creates a new room. Nothing in this repository deletes expired rooms on a clock, so a room can remain after it has expired until one of those deletes runs.
Feature suggestions. The “Suggest a feature” form stores the message (up to 2,000 characters), an optional email, the page path, the time, and either your account id or, if you are signed out, your IP address from Cloudflare’s cf-connecting-ip header. The same text is emailed to the operator addresses configured as ADMIN_EMAILS.
AI roleplay. AI roleplay is coming soon and is not live. No roleplay data is collected until it launches, and this policy will be updated then to name the provider and how long that company keeps prompts and replies. Until ROLEPLAY_API_BASE_URL, ROLEPLAY_API_KEY, and ROLEPLAY_MODEL are all set, the page says “coming soon” and the roleplay API returns an error instead of calling a model. This app does not write roleplay messages into its database. The provider is not named in this repository.
Information collected while you use the site
Sessions. Better Auth stores a session row: a token, an expiry, the account id, the IP address, and the user agent. The IP is taken from Cloudflare’s cf-connecting-ip header. This project does not set its own session length. Better Auth 1.7.7 defaults to 7 days, and it can refresh that expiry while you keep using the site. When an expired session is checked, that session row is deleted. This repository has no job that deletes every expired session on a schedule. The session cookie is httpOnly, SameSite=Lax, and named better-auth.session_token (with a __Secure- prefix on HTTPS).
Sign-in and sign-up are rate-limited, and those counters are stored in the database. The auth config uses the visitor IP so visitors do not share one bucket. Creating a room is limited per account. Suggestions are limited per account, or per IP when you are signed out.
Analytics. When a Google Analytics 4 measurement ID is configured on the server, the site loads Google’s gtag.js from googletagmanager.com. The tag config sets anonymize_ip to true. It does not override the page location, so a page view includes the full URL, including campaign parameters and click ids. The site also sends events such as which game you started, the heat level, a player count, whether you were a guest, a signup or login (method and the path that sent you there, not your email or name), signup errors as a code, Discord-link clicks, and clicks on a locked category. Card text, yes/no/maybe answers, email addresses, and names are not event parameters. Values that contain “@” are dropped before an event is sent.
After you sign up or log in, the site can also send that one event with navigator.sendBeacon to https://www.google-analytics.com/g/collect, so the hit is not lost when the page changes. To tie it to the same browser, that request reads Google’s _ga cookie and the _ga_… cookie for the measurement id. Until the hit is sent, a copy sits in session storage and in a first-party cookie named ka_auth_hit for 30 minutes. That copy is the event name and those parameters, not your email.
There is no in-app switch to turn analytics off. If the measurement ID is unset, the tag is not loaded. The measurement ID is the server variable GA_MEASUREMENT_ID. This repository does not set Google’s cookie names or a cookie lifetime.
Google’s published GA4 cookies are _ga, used to distinguish users, and _ga_ plus the measurement id, used to persist session state. Both default to 2 years. A property admin can override that expiry, from immediately up to 25 months. Browsers can also drop a first-party cookie sooner when you do not come back: Google’s cookie help names a 400-day cap in Chrome and a 7-day cap in Safari. If the property is linked to a Google Ads account, Google’s tag can set more advertising cookies. This repository does not show whether that link is on, or whether the live property has overridden the 2-year default.
On a standard Google Analytics 4 property, user-level and event-level data can be kept for 2 months or 14 months. Google’s Explorations help says properties retain 2 months by default. Analytics 360 can keep event data longer, and a standard property that becomes Large has its event-level retention reduced to 2 months. The retention setting applies to explorations and funnel reports. It does not limit standard aggregated reports. Age, gender, and interest data stay at 2 months even when the property is set longer. This repository does not record which period the live property uses, so this policy does not state a single retention number for knotty.games.
Mail we send. Transactional email goes out through Resend’s API when RESEND_API_KEY is set. That includes the confirmation email, the password-reset email, and notices to operators (a new account, a suggestion, and an under-18 birthdate). The from-address falls back to hello@knotty.games. Without an API key, the send is skipped and logged on the server. Resend therefore receives the recipient address and the message when email is enabled. Resend’s public documentation says that, while the account is active, email content, metadata, delivery events, logs, and metrics are kept for 30 days on the Free, Pro, and Scale plans, and that this stored data is held in the United States. Enterprise plans can use a different retention period. This repository does not record which plan is in use. Resend also says backups are kept for 7 days, and that data left after the Resend account is closed is deleted within 90 days.
Mail you send us. Messages delivered to @knotty.games, including hello@knotty.games, are stored: sender, recipient, subject, text, HTML (each body part truncated), size, and the time received. If a forward address is set on the mail worker, a copy is forwarded there. That destination is an operator setting and is not published in this policy. Write to us at hello@knotty.games.
How long we keep it
What the code actually does:
- A shared room expires 24 hours after the last move. It is deleted when that room is opened after expiry, or when any new room is created. It is not deleted by a scheduled job in this repository.
- A session expires after 7 days under Better Auth’s default (refreshed while you use the site). That session row is deleted when the expired session is checked. Other expired rows are not swept on a timer by this repository.
- A password-reset link expires after one hour. A confirmation link uses Better Auth’s one-hour default.
- Browser session storage ends with the browser session. Local storage stays until you clear it or, for the profile, sign out.
- The pending-analytics cookie lasts 30 minutes. The operator analytics cookie lasts 400 days. The brand-preview cookie lasts 30 days.
We keep an account, and the profile stored on it, until you delete the account or ask us to delete it. There is no delete button in the product, so asking means emailing hello@knotty.games. Deleting an account removes the profile and the sessions, and removes rooms that account hosts. A room you only joined as the guest can keep its game state until that room expires, with your account id cleared. Suggestions, inbound mail, verification rows, and rate-limit rows have no deletion schedule in this code. They stay until someone deletes them. A suggestion can remain with the account link removed. Mail you sent us stays in the inbox until an operator deletes it. Nothing in this repository runs a job that purges expired rooms or sessions on a clock.
Access, correction, and deletion
Email hello@knotty.games to ask for a copy of the account data we store, to correct it, or to delete it. There is no delete button in the product. Say which email the account uses so we can find it. We respond within 30 days. We can delete the account, which cascades to the profile and sessions, and we can delete leftover suggestions, guest-room state, and inbox messages tied to you. Those extra deletes are not automatic.
You can clear this site’s cookies and site data in your browser, which removes the age confirmation, the local profile, and the preference keys. You can reset a password from the account page. You can stop analytics by blocking googletagmanager.com and google-analytics.com. The site does not offer its own opt-out switch.
Governing law and venue are stated in the terms of service: the laws of the State of Delaware, and the state and federal courts in King County, Washington. This policy does not claim the GDPR, the CCPA, or another privacy statute.
People under 18
Knotty is not for anyone under 18, and we do not want their information. If you believe a minor has an account, email hello@knotty.games and we will delete it. An optional birthdate that calculates to under 18 notifies the operators. It does not, by itself, delete the account.
Changes to this policy
We will post changes on this page and update the date at the top. The terms of service explain the rules for using the site.