Skip to main content

Legal

Cookies & Local Storage

Effective 2026-09-29

Our approach

Nisatsu uses first-party cookies and browser storage to keep you signed in, secure authentication and account-linking flows, preserve settings you request, and recover in-progress learning actions. We also use tab-scoped first-party storage for campaign attribution. That attribution storage does not contact an advertising partner or enable cross-site tracking.

The one exception is advertising measurement, and only with your consent. While we are running an ad campaign for Nisatsu, our public pages (such as the sign-in page and these legal pages) show a banner asking whether our advertising partners may set cookies to measure how our ads perform. Nothing loads unless you choose Accept; Decline works with one click and the app works exactly the same. When no campaign is configured, the default, no banner appears and no partner cookie is set. You can change your answer at any time via the "Cookie preferences" link in the footer (shown while a campaign is running). If your browser sends a Global Privacy Control signal, we treat it as a standing Decline automatically.

What we store

This is the current inventory of first-party storage Nisatsu creates. The authentication entries are strictly necessary for the requested sign-in, sign-up, or account-link flow. Preference and learning-continuity entries provide settings or actions you request. The first-party attribution entry is session-only and does not load a partner. The checkout entries are strictly necessary for a card payment and exist only after you open the Pro checkout. The final partner-cookie group exists only with your consent while an ad campaign is running. Lifetimes are upper bounds; most short-lived values are cleared as soon as their flow completes.

Session

  • nisatsu_session (cookie, HttpOnly, Secure, SameSite=Lax, 30 days, path /), keeps you signed in. Expires after 30 days or when you sign out. On our deployed sites the browser shows it as __Host-nisatsu_session; the __Host- prefix is a browser security feature that stops other subdomains from tampering with it.
  • nisatsu_session_jwt (cookie, HttpOnly, Secure, SameSite=Lax, 30 days, path /), a short-lived signed companion to your session that lets us verify you're signed in without an extra network round-trip on each request. Refreshed automatically while you use the app and cleared when you sign out. On our deployed sites the browser shows it as __Host-nisatsu_session_jwt.

OAuth round-trip (Google / Apple)

  • nisatsu_oauth_pkce (cookie, HttpOnly, Secure, SameSite=Lax, 10 min, path /api/auth), anti-CSRF PKCE verifier that binds the OAuth token exchange to this browser. Cleared on callback regardless of outcome.
  • nisatsu_oauth_next (cookie, HttpOnly, Secure, SameSite=Lax, 10 min, path /), short-lived stash of the page you were trying to reach when you started a Google or Apple sign-in, so we can return you there after the OAuth round-trip.
  • nisatsu_oauth_mobile (cookie, HttpOnly, Secure, SameSite=Lax, 10 min, path /api/auth), marks the OAuth round-trip as initiated by the mobile app so the callback hands the session token back through the nisatsu:// deep link instead of setting a web cookie.
  • nisatsu_oauth_app_challenge (cookie, HttpOnly, Secure, SameSite=Lax, 10 min, path /api/auth), binds a mobile OAuth exchange code to the verifier held by the app. Cleared after the callback.

Magic-link sign-in

  • nisatsu_ml_next (cookie, HttpOnly, Secure, SameSite=Lax, 60 min, path /), short-lived stash of the page you were trying to reach when you requested a magic link, so we can return you there after clicking the email. It lasts as long as the link itself, so opening the email an hour later still returns you where you were.
  • nisatsu_ml_pkce (cookie, HttpOnly, Secure, SameSite=Lax, 60 min, path /api/auth), anti-CSRF PKCE verifier that binds a magic link to the browser that requested it. Cleared on callback.

Sign-up verification

  • nisatsu_age_affirmed (cookie, HttpOnly, Secure, SameSite=Lax, 1 hour, path /api/auth), transaction-bound proof that the minimum-age affirmation accompanied the OAuth or magic-link sign-up flow. Cleared when the flow completes or fails.
  • nisatsu_signup_marketing_consent (cookie, HttpOnly, Secure, SameSite=Lax, 1 hour, path /api/auth), transaction-bound proof that you checked the optional marketing-email box during an OAuth or magic-link sign-up flow. It is bound to that flow's PKCE verifier and cleared when the flow completes or fails.

Account linking

  • nisatsu_link_email (cookie, HttpOnly, Secure, SameSite=Lax, 1 hour, path /api/account/link), signed state cookie that binds an "add an email sign-in method" flow to your current account so the verification email can only ever attach to you.
  • nisatsu_link_oauth (cookie, HttpOnly, Secure, SameSite=Lax, 10 min, path /api/auth), signed state cookie that binds an "add Google / Apple as a sign-in method" flow to your current account so the OAuth callback can only ever attach to you.
  • nisatsu_link_ticket (sessionStorage), short-lived handoff token that carries an in-progress account-link from before you signed out to the linking screen after you sign back in. Read once and cleared as soon as the link is redeemed, and dropped automatically when the browser tab closes.

Browser-side preferences and learning continuity

  • nisatsu_theme (localStorage), remembers your light/dark/system preference so the UI doesn't flash on first paint.
  • nisatsu_reading_aid_mode (localStorage), caches your account's Japanese reading-aid choice (Romaji, Furigana, or None) so protected pages render consistently while the account setting hydrates.
  • nisatsu_furigana_mode (localStorage), legacy compatibility cache for furigana and Chinese pinyin display (Always, On tap, or Never). Current Japanese clients use nisatsu_reading_aid_mode; older clients and Chinese reader controls still use this key.
  • nisatsu_last_auth (localStorage), remembers whether you last signed in by email or by phone so the sign-in form opens to that method.
  • nisatsu_qa_mode (cookie), staging-only QA fixture switch used by our own testing tools to preview empty, gated, and error screens; production ignores it entirely and nothing in the product sets it for visitors.
  • nisatsu_privacy_preferences (localStorage), local mirror of your Account → Settings → Privacy & data choices (analytics opt-out, "Do Not Sell or Share") so the browser-side error monitor can respect them before any network request finishes. Cleared when you sign out.
  • nisatsu_telemetry_consent (localStorage), records your answer to the one-time "Help us improve Nisatsu?" prompt shown in the signed-in app (Allow or Not now) so it is not asked again on this browser, and so the browser-side error monitor and usage events stay off until you have answered. Kept across sign-out, like the matching setting in the mobile app, so a "Not now" also applies to any other account signed in on this browser afterwards and switches product analytics off for it too. You can change the choice at any time in Account → Settings → Privacy & data, which turns analytics back on for the account you are signed in as, or remove the record by clearing browser storage.
  • nisatsu_active_generation (localStorage), keeps the current story-generation job ID so progress can resume after a reload. Cleared when the job finishes, fails, is missing, reaches the client timeout, or when you sign out.
  • nisatsu_quiz_setup (localStorage), remembers your selected quiz mode, thresholds, answer format, direction, and reading-display choice until you change them or clear browser storage.
  • nisatsu_pending_vocab_grades (localStorage), temporarily queues a word ID, answer correctness, attempt ID, and timestamp when a vocabulary answer cannot sync. Entries are removed after successful delivery or when you sign out.
  • nisatsu_quiz_completion_outbox (localStorage), temporarily holds the totals of a quiz round you ended (session ID, items answered, items correct) when the completion cannot reach our servers, so the round is recorded once you are back online. Removed after successful delivery or when you sign out.
  • nisatsu_pending_data_export (localStorage), stores only the time you asked to sign in again for a protected data download. It is accepted for 15 minutes, removed when Privacy & data next opens, and never contains account data or credentials.
  • nisatsu_legal_notice_ack (localStorage), written by earlier versions of the site to record the legal-notice version acknowledged on this browser. Nothing writes or reads it now: your acknowledgement is stored on your account only, so a notice accepted on this browser never counts for another account signed in here. A value left by an earlier version stays until you clear browser storage.

Tab-scoped handoffs and first-party attribution

  • nisatsu_utm (sessionStorage), stores first-touch utm_source, utm_medium, utm_campaign, utm_content, and utm_term values for the current tab so a new sign-up can be attributed to the link that brought you to Nisatsu. The marketing and app domains keep separate tab-scoped copies. This first-party value is stored regardless of the partner-cookie choice, but it never loads a partner script by itself.
  • ns-reader-scroll:<storyId> (sessionStorage), one-time scroll position used to return you to the same place in a story after opening word details. Consumed on first return or removed when the tab closes.

Checkout (Stripe under RevenueCat)

  • __stripe_mid (cookie, Secure, SameSite=Strict, about 1 year, path /), set by Stripe.js on our domain for payment fraud prevention. The Pro checkout runs inside the app page: RevenueCat opens its payment form there and loads Stripe.js to take the card, so the cookie is first-party on nisatsu.app. Strictly necessary for the payment, and set only when you open the Pro checkout, never on any other page.
  • __stripe_sid (cookie, Secure, SameSite=Strict, about 30 minutes, path /), the short-lived companion to __stripe_mid, used by Stripe.js for the same fraud-prevention purpose during one checkout session. Set only when you open the Pro checkout.

Advertising measurement (only with your consent)

  • nisatsu_consent (cookie, Secure, SameSite=Lax, 12 months), remembers your Accept/Decline answer to the advertising-cookies banner so it doesn't re-ask. Because nisatsu.com and nisatsu.app are separate domains, each stores its own first-party copy. An account-level or public Do Not Sell or Share request visits both origins in sequence and revokes both copies. Set only when you answer the banner or opt out; if we materially change the partner scope, the banner asks again before any new partner loads.
  • Partner cookies (Google _ga*, _gcl_*, and _gac_*; Meta _fbp and _fbc; TikTok _ttp, _tt_*, ttcsid, ttcsid_*, ttclid, and the third-party _pangle cookie where that network applies), set by our advertising partners only after you choose Accept, to measure ad performance. TikTok documents a 13-month lifetime for its listed cookies; other exact lifetimes are controlled by the partner. They are never set by Nisatsu if you decline, if your browser sends Global Privacy Control, or while no campaign is configured. If you withdraw consent later, we remove first-party copies on a best-effort basis and stop all further loading.

On mobile, the corresponding session token is stored in your device's secure keychain (iOS Keychain / Android Keystore) via Expo SecureStore. It is not an HTTP cookie.

Third-party storage

The Pro checkout is provided by RevenueCat and takes your card through Stripe. Its payment form runs inside the app page, so the two Stripe fraud-prevention cookies it needs are listed above as first-party storage. Any other cookie RevenueCat or Stripe sets when you interact with their own pages, such as the receipt or subscription-management pages they host, is set on their domains. The Stytch sign-in flow may likewise set cookies on Stytch's domain when you interact with it. Those cookies are governed by RevenueCat's, Stripe's, and Stytch's privacy notices respectively.

Controlling storage

You can clear Nisatsu's cookies and local storage at any time via your browser settings. Clearing the session cookie will sign you out.

More

See our Privacy Policy for the full picture of what data we collect and who we share it with.

Questions

Questions about cookies or local storage? Email contact@nisatsu.com.

Cookies & Local Storage · Nisatsu