Skip to main content

Cookie Policy

Last updated: 17 August 2026

What Are Cookies?

Cookies are small text files stored on your device when you visit a website. We also use browser local storage for some preferences. This policy explains what we store, why, and how you can control it.

Your Choices

When you first visit NumDojo, you can accept all cookies, use essential cookies only, or open Manage preferences to choose Google Analytics and OpenAI Ads measurement separately. You can change either choice at any time via in the site footer. Essential cookies cannot be disabled because the platform cannot function without them.

Google Analytics stays blocked until you select it and sign in to an account recorded as adult. OpenAI Ads measurement has a separate choice and the same account-age boundary. Signed-out visitors can save choices for later, but neither service runs while they are signed out. NumDojo does not treat measurement consent as consent to future user-level ad personalisation.

Cookies We Set

NameProviderTypePurposeDuration
accessTokenNumDojoEssentialKeeps you signed in (short-lived session JWT)15 minutes
refreshTokenNumDojoEssentialSecurely renews your session without re-entering credentials7 days
_csrfNumDojoEssentialProtects against cross-site request forgery on state-changing requests1 hour
oauth_state_nonceNumDojoEssentialValidates OAuth sign-in state (Google / GitHub)10 minutes
_gaGoogle AnalyticsOptional measurementDistinguishes unique visitors for usage statistics2 years
_ga_*Google AnalyticsAnalytics (optional)Persists session state for GA4 measurement2 years
numdojo_openai_ads_consentNumDojoEssential preferenceShares only your OpenAI Ads measurement choice with trusted server conversion checks180 days
__oppref, __obrefOpenAI Ads measurementOptional measurementAttributes an eligible adult conversion to an OpenAI ad without storing raw contact detailsNot documented; disabled pending review

Browser Local and Session Storage

These are not HTTP cookies. Local storage can remain after you close the browser, while session storage normally lasts for the current tab session. NumDojo does not apply a time-based expiry unless the table says otherwise.

KeyStoragePurposeRetention
numdojo_cookie_consentLocal storageStores your separate Google Analytics and OpenAI Ads choices, when you updated them, and the consent format versionNo programmed expiry. Replaced when you change your choices and retained until you clear site data.
authTokenLocal storageShort-lived access JWT copy for API and real-time features; httpOnly cookies remain the primary session storeThe JWT expires after 15 minutes. The browser copy is replaced on refresh and removed on sign-out or an invalid session. An expired copy can remain until then or until you clear site data.
reducedMotion, soundEnabled, fontSize, highContrast, autoPlayAnimations, darkMode, colorBlindMode, animationSpeed, screenReaderEnabled, keyboardShortcuts, keyboardNavigationEnabled, focusIndicatorStyle, hapticFeedbackEnabledLocal storageStores accessibility, display, sound, animation, keyboard, focus, and haptic preferencesNo programmed expiry. Replaced when a setting changes. darkMode can also be removed by the cache-clearing page. Otherwise retained until you clear site data.
ageThemeOverrideLocal storageStores an age-group theme override on this deviceNo programmed expiry. Removed when the override is reset to automatic, or when you clear site data.
numdojo_sound_settingsLocal storageStores detailed sound volume and mute settingsNo programmed expiry. Replaced when a sound setting changes and retained until you clear site data.
numdojo_haptic_settingsLocal storageStores haptic feedback status and intensityNo programmed expiry. Replaced when a haptic setting changes and retained until you clear site data.
numdojo:trachtenberg-x11-best-scoreLocal storageStores your best score for the multiplication-by-11 worksheet on this deviceNo programmed expiry. Replaced when you check a worksheet and retained until you clear site data.
numdojo:virtual-soroban-practiceLocal storageStores your virtual Soroban best run, daily streak, and last practice day on this deviceNo programmed expiry. Updated after a correct answer. A missed day resets the streak when you next record a correct answer. Retained until you clear site data.
numdojo_battle_analyticsLocal storageStores completed Battle session and problem-attempt history, including answers, accuracy, scores, and response timesNo time-based expiry. Limited to the newest 100 completed sessions; older sessions are dropped as new ones are added. Otherwise retained until you clear site data.
battle_failed_sessionsLocal storageStores Battle session payloads that could not be sent to the server so they can be retriedNo time-based expiry. Limited to 50 sessions. A session is removed after a successful retry; otherwise it remains until you clear site data.
usernameLocal storageA legacy value read to identify your own entry in some league and guild views; the current frontend does not create or update itNo current write or deletion path. A value left by older code can remain until you clear site data.
battle_snapshotSession storageStores the current Battle room, scores, problem, and timestamp for short reconnection recovery in the same tabRecovery accepts it for 30 seconds. It is removed when a Battle ends normally, while the browser clears any remaining value when the tab session ends or you clear site data.
redirectAfterLoginSession storageRecords the protected route present when sign-in is required; current navigation uses the next URL parameter rather than reading this keyNo earlier removal is programmed. The browser clears it when the tab session ends, or it is removed when you clear site data.

Third-Party Cookies

Stripe (payments)

When you subscribe or manage billing, Stripe Checkout and the Customer Portal may set their own cookies on stripe.com for fraud prevention and payment processing. See Stripe's Privacy Policy.

Google Analytics

Only loaded after you select Google Analytics and sign in to an account recorded as adult. IP addresses are anonymized and ad signals are disabled in our GA4 configuration. Measurement ID: G-3P9MDPCB6X.

OpenAI Ads measurement

This is loaded only after you separately select OpenAI Ads measurement, sign in to an account recorded as adult, and an approved campaign Pixel ID is configured. Registration matching uses a one-way hash of the email address. Raw email addresses are not sent through the measurement event, and events are opted out of future user-level personalisation. OpenAI's current measurement documentation does not state how long the __oppref and __obref cookies last. OpenAI Ads measurement remains disabled until that duration and the related retention handling are reviewed.

Managing Cookies in Your Browser

You can also block or delete cookies through your browser settings. Disabling essential cookies will prevent you from staying signed in. Clearing local storage will reset UI preferences, worksheet and virtual Soroban practice figures, and your cookie consent choice (the banner will appear again).

Contact

Questions? Contact us at support@numdojo.com.