Privacy Policy
Curator - FRC AI Assistant Last updated: September 24, 2026
1. Overview
This Privacy Policy explains how Curator ("the Service", "we", "us") collects, uses, and protects information about you when you use our AI-powered FRC assistant. We are committed to being transparent and collecting only what is necessary to operate the Service.
We do not sell your personal information. We do not share your personal information with third parties for cross-context behavioral advertising or any advertising purpose.
Curator does not track you. Under Apple's definition of tracking, we do not link data collected in Curator with data collected by other companies' apps or websites for advertising or measurement purposes, and we do not share your data with data brokers. Optional analytics, described below, are configured to block cross-context signal sharing and ad personalization, are never active until you explicitly opt in on the website, and are not available in the Curator iOS and Android apps.
2. Information We Collect
2a. Guests (unauthenticated users)
- A session cookie tracking whether you have accepted the Terms of Service for the current browser session
- Server-side counters used to enforce the guest message limit (a recurring daily quota that resets every 24 hours - no account is ever required to keep using the Service)
- A persistent
guest_session_idcookie that links your browser to your guest conversations stored in our database (see §7) - A cookie recording your cookie-consent choice (
necessaryoraccepted) - Optional sidebar preference cookies recording whether the sidebar is open and what width you chose
- Browser cache entries created by the app's installable web-app/service-worker layer for offline support; this cache is limited to the offline fallback page, manifest, and app icons
- Your chat messages: stored server-side in our database, linked to your
guest_session_idcookie, and also cached in your browser'slocalStoragefor fast access. If you sign in, your guest conversations are transferred to your account.
2b. Authenticated users (Google or Apple sign-in)
- From Google OAuth: your name, email address, and profile picture URL
- From Apple Sign-In: your name and email address (Apple only sends your name on the very first sign-in; profile pictures are not provided by Apple)
- Onboarding profile: your preferred name and optional FRC team number
- Conversation history: all messages you send and receive, stored in our database so they persist across devices
- Projects: project names, icon/color choices, chat-to-project organization, and hidden AI-generated project context summaries derived from chats inside each project
- Moderation records: if your account is suspended, we store the affected email address, suspension status, timestamp, and any admin-entered reason tied to that action
- Sharing preferences: whether a conversation has been marked public by you
- Admin-authored blog content: if you are an admin, blog post drafts and publication metadata you create may be stored in our database and, when published, shown publicly with your preferred name (or your account name if no preferred name is set)
- Account settings: your saved default chat style preference (
VeteranorRookie), onboarding completion timestamp, and Terms of Service acceptance timestamp - Account metadata: account creation date, last active date
2c. All users
- Chat messages and AI processing: message content is sent to OpenRouter (our LLM provider) for processing. Depending on the model/provider OpenRouter routes your request to (especially some free models), prompt and response data may be logged, retained, or used by that provider for abuse monitoring, service improvement, or model training under their terms. Do not submit secrets or highly sensitive information in chats. See OpenRouter's privacy policy at openrouter.ai/privacy.
- Team context lookups: if your saved team number is available and a chat needs live event context, relevant query data is sent to The Blue Alliance through our server-side integration.
- Public shared chats: if an authenticated user chooses to make a chat public, that conversation becomes accessible to anyone with the chat URL until the owner turns sharing off or deletes the chat.
- Search queries: if web search is triggered, including when you enable Deep search, your query is sent to LangSearch. Deep search may run multiple web searches until enough context is gathered or the search provider rate-limits the request. See LangSearch's privacy policy for details.
- Response feedback: if you use response feedback controls, we store the feedback type, message ID, account ID if signed in, IP address, and timestamp in operational logs so admins can improve retrieval and answer quality.
- Support requests: if you use the support form, we collect the details you submit, which may include your name, email address, subject, message, current page path, browser user agent, IP address, and your account ID if signed in.
- Moderation flags: authenticated user messages may be automatically scanned for profanity, harassment, threats, sexual content, or similarly inappropriate language. Matching messages can create an internal moderation report containing the message ID, conversation ID, account ID, matched terms, and flag reason for admin review.
- Error and performance telemetry: we use Sentry to capture application errors, request context, performance traces, and diagnostic metadata such as URLs and browser/device information. We do not intentionally send cookies, authorization headers, provider API keys, or full request bodies to Sentry. Browser Session Replay is disabled by default and, if enabled for debugging, is configured to mask text and block media. Sentry acts as a data processor on our behalf and does not sell or share your personal data. See Section 4 for details.
- Cookie-free performance analytics: Cloudflare Web Analytics may collect aggregate pageview and performance metrics, including navigation timing and Core Web Vitals-style measurements, using a lightweight browser beacon that does not rely on cookies or advertising identifiers.
- Operational logs: we store application logs for support, abuse prevention, debugging, security auditing, and reliability work. These logs can include request paths, IP address, account ID, admin actions, and error details. When admins view user chat transcripts through the admin panel, we log that access for accountability.
- Rate-limit metadata: we store per-scope counters keyed to your account ID or network metadata so we can slow abusive traffic and protect the Service.
- Search indexing notifications: when indexable public Curator pages are added or updated, we may send the affected page URLs to IndexNow-participating search engines so they can recrawl those pages faster. News/blog URLs are excluded from these submissions.
- Analytics usage data (consent required): if you explicitly allow analytics through the cookie consent banner, we use Google Analytics 4 to collect aggregated usage data - for example, page views, device/browser information, approximate region, and interaction events - to understand and improve the Service. Google Analytics does not load until you actively opt in. If you decline or ignore the banner, no GA script loads, no GA cookies are set, and no GA data is collected. When active, GA is configured with Google Signals and ad personalization signals disabled and IP anonymization enabled, so it is not used to link your activity with data from other companies' apps or websites and is not used for advertising. You can change this choice at any time from the cookie preferences control in Settings. The Curator iOS and Android apps never load Google Analytics and never show a cookie consent prompt, so no analytics cookies are set in the apps.
- Server logs: standard web server request logs (IP address, timestamp, user agent) retained for up to 30 days.
3. How We Use Your Information
- To provide and improve the Service
- To authenticate you via Google or Apple and persist your conversation history
- To organize your saved chats into personal projects and apply hidden project-scoped context only within those projects
- To store and apply your saved preferred name, optional team number, onboarding status, account-level chat style preference, and account-level Terms of Service acceptance
- To honor your choice to publish or unpublish shared chat links
- To let admins draft, edit, publish, and remove public blog posts about Curator updates
- To detect, review, and act on profanity or other inappropriate content through manual reports and automatic moderation flags
- To enforce the guest message limit and Terms of Service acceptance
- To record, honor, and later update your cookie-consent preference
- To generate AI responses grounded in FRC documentation
- To collect optional response feedback and identify retrieval or citation quality issues
- To enrich applicable answers with live event context from The Blue Alliance when your saved team number is available
- To respond to support requests and account/privacy questions
- To generate on-demand account data exports when you request them from Settings
- To enforce rate limits and investigate abuse or reliability issues
- To monitor application errors, reliability, and performance through Sentry
- To monitor performance and usage trends through aggregate analytics, only after you consent
We do not use your data for advertising. We do not sell your data. We do not share your data with third parties for cross-context behavioral advertising.
4. Third-Party Services
The following services receive data as part of operating the Service. None of these services receive your data for advertising purposes, and none are permitted to sell data we share with them under our agreements.
| Service | Purpose | Data they receive | Their Privacy Policy |
|---|---|---|---|
| Google OAuth | Authentication (web, iOS, and Android) | Email, name, profile picture | policies.google.com/privacy |
| Apple Sign-In | Authentication (web, iOS, and Android) | Email, name (first sign-in only). On iOS and Android, also sends account-lifecycle server-to-server notifications (see §6) | apple.com/legal/privacy |
| OpenRouter | LLM routing and inference | Chat message content; upstream model providers may process and retain prompts under their own terms | openrouter.ai/privacy |
| The Blue Alliance | Live team, event, and match context | Team number, query context | thebluealliance.com/privacy |
| LangSearch | Web search for grounding AI responses | Search query text | (see LangSearch docs) |
| Sentry | Error monitoring and performance tracing | Error context, URLs, and device info. Session Replay is disabled by default and, if enabled, masks text and blocks media. Sentry processes this only on our behalf under a Data Processing Addendum and does not sell or share this data. | sentry.io/privacy/ |
| Cloudflare Web Analytics | Cookie-free aggregate site analytics | Aggregate, non-identified performance metrics. No cookies or advertising identifiers used. | cloudflare.com/privacypolicy/ |
| Google Analytics 4 | Aggregate usage analytics on the website - only loaded after you explicitly allow analytics; never loaded in the iOS or Android apps | Page views, device/browser info, approximate region, interaction events. Only active with your consent. Google Signals and ad personalization signals are disabled; IP anonymization is enabled. | policies.google.com/privacy |
| IndexNow | Notifies search engines when indexable public pages change | Indexable public page URLs only; news/blog URLs are excluded | indexnow.org/documentation |
| MinIO (self-hosted) | Document storage | PDF documents uploaded by admins | Self-hosted, no third party |
A note on Google Analytics, data sharing, and tracking
Google Analytics 4 collects usage data and shares it with Google. Under broad interpretations of laws like the California Consumer Privacy Act (CCPA), sharing a visitor identifier with a third-party analytics provider could be considered "sharing" of personal data. It could also, if misconfigured, meet Apple's definition of "tracking" (linking data with other companies' apps/websites for advertising or measurement, or sharing with data brokers). We mitigate both risks by:
- Requiring explicit opt-in consent before Google Analytics loads. GA is blocked by default and only activates if you click "Allow analytics" on the cookie banner or preferences dialog.
- Disabling Google Signals (
allow_google_signals: false), which prevents Google from using GA data for cross-device or cross-context advertising reporting. - Disabling ad personalization signals (
allow_ad_personalization_signals: false) and enabling IP anonymization. - Not linking Google Analytics to Google Ads or any advertising product. We do not use GA data for behavioral advertising.
- Not selling or sharing your data with Google or anyone else for advertising purposes.
If you do not consent to analytics, Google Analytics never loads and no data is sent to Google from your session. In the Curator iOS and Android apps, Google Analytics is disabled entirely and no cookie consent prompt is shown. Because of these restrictions, Curator's use of Google Analytics does not constitute tracking under Apple's App Tracking Transparency framework, and Curator does not request ATT permission.
5. Data Storage
- User data and conversation history are stored in a self-hosted PostgreSQL database.
- Project metadata, chat project assignments, and hidden project context summaries are stored in PostgreSQL with your account data.
- Saved onboarding fields, including preferred name, optional team number, onboarding completion time, and Terms of Service acceptance time, are stored in the same PostgreSQL account record.
- Public/private sharing status for authenticated conversations is stored alongside the conversation record in PostgreSQL.
- Admin-authored blog posts, publication timestamps, and the associated author account reference are stored in PostgreSQL.
- Moderation reports, matched-term metadata, and banned-email records are stored in PostgreSQL.
- Support requests, application logs, admin audit logs, and rate-limit counters are stored in PostgreSQL.
- Response feedback is stored in PostgreSQL as an operational log entry.
- The installable web app stores a browser-managed offline cache of the offline fallback page, manifest, and app icons on your device. It does not intentionally cache route HTML or Next.js build assets in the app service-worker cache.
- PDF documents, including season-specific references and general team reference files, are stored in a self-hosted MinIO instance.
- Vector embeddings are stored in a self-hosted Qdrant instance.
- Short-lived server caches may hold copies of public pages and admin read responses for performance until those caches expire or are invalidated.
- No user data is stored on third-party cloud storage.
6. Data Retention
- Guest conversations: stored server-side in our database, linked to your
guest_session_idcookie, and also cached in your browser'slocalStorage. Guest conversations and their messages are deleted 90 days after creation. If you sign in, your guest conversations are transferred to your account and retained according to the authenticated-user policy above. Clearing your browser data removes the local cache only - the server copy is retained until the 90-day window expires or you sign in and then delete the conversations from your account. - Deleted conversations: deleting a chat (guest or signed-in) moves it to a "Recently Deleted" area instead of removing it immediately. From there you can restore it or delete it forever. Chats left in Recently Deleted are permanently deleted automatically after 30 days. A publicly shared chat stops being reachable via its share link as soon as it's deleted, even while it's still recoverable from Recently Deleted.
- Offline app cache: limited to the offline fallback page, manifest, and app icons; stored in your browser until the browser clears site data, the service worker replaces the cache during an update, or you manually remove the site's stored data.
- Authenticated user data: retained for as long as your account exists. This includes saved onboarding profile fields, chat-mode preference, Terms of Service acceptance state, project metadata, hidden project summaries, and conversation history. You may delete your account from the Settings page. Account deletion removes your account, saved chats, projects, settings, sessions, linked sign-in records, user reports tied to deleted chats, and other rows that cascade from the account record. Support requests and operational logs linked to the deleted account are redacted where retained for support, security, accountability, or abuse-prevention needs.
- Apple account-lifecycle notifications (iOS and Android): if you signed in with Apple on iOS or Android, Apple may notify us server-to-server when you delete your Apple Account or revoke Curator's Sign in with Apple access. A permanent Apple Account deletion triggers the same account deletion described above. Revoking Sign in with Apple access (without deleting your Apple Account) unlinks Apple as a sign-in method for your Curator account without deleting your other account data.
- OpenRouter/upstream model-provider data: prompts and model outputs sent for inference may be retained by OpenRouter and/or the selected upstream model provider according to their own retention and training policies (which can vary by model tier, including free models).
- Projects: retained for as long as your account exists unless you delete a project. Deleting a project removes its project metadata and hidden summary while returning its chats to normal history.
- Moderation data: moderation reports and banned-email records are retained until they are manually cleared, no longer needed for safety or abuse review, or your account and related moderation history are deleted.
- Account export packages: generated on demand from your current account data when you request an export from Settings and not stored by the Service after the response is delivered.
- Public shared chats: remain publicly accessible until you make the chat private again or delete it.
- Admin-authored blog posts: retained until they are deleted or unpublished by an admin; published posts remain publicly accessible until removed or replaced.
- Support requests, application logs, and admin audit logs: retained until they are manually deleted or no longer needed for support, security, accountability, or operational debugging. If you delete your account, support requests and application logs linked to that account are redacted; admin audit logs may retain limited action metadata needed for accountability.
- Response feedback: retained until it is manually deleted or no longer needed for product quality review.
- Rate-limit counters: retained for up to 7 days before cleanup.
- Server logs: retained for 30 days, then deleted.
- Analytics data: retained according to Google Analytics property retention settings configured by the operator, and only applies if you have consented to analytics cookies.
7. Cookies
Necessary cookies (always active):
tos_accepted- records that a guest browser session has accepted the Terms of Service (session cookie)guest_session_id- persistent identifier linking your browser to your guest conversations stored on our servers. Set when you start your first guest conversation; expires after 90 days. Automatically deleted when you sign in or sign out. This cookie is set as HttpOnly.cookie_consent- records your cookie consent choicesidebar_state- stores whether the sidebar is expanded or collapsedsidebar_width- stores your chosen sidebar widthadmin_sidebar_collapsed- stores whether the admin navigation panel is expanded or collapsed (admin accounts only)authjs.session-tokenor__Secure-authjs.session-token- Auth.js session JWT (authenticated users only)authjs.csrf-token- protects the sign-in flow from cross-site request forgeryauthjs.callback-url- remembers where to return you after sign-in (if set by Auth.js)
Analytics cookies (only set after you explicitly allow them):
_ga,_ga_*- Google Analytics cookies used to distinguish sessions and measure aggregate site usage. These are only set on the website if you explicitly allow analytics through the cookie banner or Settings, are never set in the iOS or Android apps, and are configured with Google Signals and ad personalization signals disabled (see §4).
We do not use advertising cookies. We do not use cookies for cross-site or cross-app tracking. We do not use any cookie, SDK, or identifier to link your activity in Curator with your activity in other companies' apps or websites, and we do not request Apple's App Tracking Transparency permission because Curator does not perform tracking as Apple defines it.
Curator also stores local browser values for app preferences and guest UI state, including curator:cookie-consent, curator:guest-message-count, curator:factCheck, curator:searchMode, and the legacy curator:deepSearch value. These are stored in localStorage, not cookies, and are never shared with any third party.
On the website, you can change your analytics cookie choice at any time from the cookie preferences control in Settings. The iOS and Android apps have no analytics cookies, so this control is not shown there.
8. Your Privacy Rights
Depending on where you live, you may have rights under laws such as the California Consumer Privacy Act (CCPA/CPRA), the General Data Protection Regulation (GDPR), or other applicable privacy laws. Regardless of where you are located, we extend the following rights to all users:
- Access: request a copy of the data we hold about you
- Deletion: delete your account and associated account data at any time from Settings, subject to limited redaction-based retention for support, security, accountability, and abuse-prevention records
- Portability: export your account data, including chats, project metadata, hidden project summaries, saved account settings, and support requests
- Correction: update your preferred name, team number, or other profile fields from Settings
- Opt-out of analytics: withdraw analytics consent on the website at any time via the cookie preferences control in Settings (analytics never run in the iOS or Android apps)
California residents (CCPA/CPRA): You have the right to know what personal information we collect, to delete it, to correct it, and to opt out of the sale or sharing of your personal information. We do not sell or share your personal information. You also have the right to non-discrimination for exercising these rights.
To make a privacy request, use the Support section in Settings, the Support page, or open an issue on the project repository.
We may retain limited moderation records when reasonably necessary to enforce the Terms, investigate abuse, or document account suspensions.
9. Children's Privacy
The Service is intended for FRC team members, mentors, and coaches. FRC participants may include students under 18, and guest chatting without an account has no age requirement. Creating an account (Google or Apple sign-in), however, requires you to be at least 13 years old, in compliance with the U.S. Children's Online Privacy Protection Act (COPPA). Before any sign-in attempt, we show a neutral age-confirmation screen; account creation does not proceed unless you confirm you are 13 or older. We do not knowingly collect personal information via an account from anyone under 13. If you believe a child under 13 has created an account or otherwise provided us personal information, contact us through the Support page and we will delete it promptly.
10. Changes to This Policy
We may update this Privacy Policy from time to time. The "Last updated" date at the top reflects any changes. We will notify authenticated users of material changes via the app.
11. Contact
For privacy questions, data deletion requests, or to exercise any of your rights under this policy, use the Support section in Settings, the Support page, or open an issue on the project repository.