Privacy
Last updated 2026-08-10
Wanilog runs in your browser. Your WaniKani data is fetched with your own API key and cached on your device; there is no Wanilog account and no general application backend. The table below is the complete list of what ever leaves your device. The first row is how the app works at all; every other row can be turned off, though the reply check stops only when you log out.
What leaves your device
| Where | What | Default | Turn it off |
|---|---|---|---|
| WaniKani API | Your API key, with every request for your WaniKani data | always | Log out |
| PostHog analytics | Usage events, session replays, and crash reports, tagged with your WaniKani username and level | on | Settings |
| Study history backup (Redis) * | Per-day activity counts and the SRS timeline | on | Settings → Advanced |
| Review history (Supabase) * | A per-item record of your reviews | on (same switch) | Settings → Advanced |
| Achievement sync (Redis) * | The badges you have earned, with dates | on (same switch) | Settings → Advanced |
| Public profile (Redis) * | An aggregate snapshot of your stats | off until you publish | Unpublish |
| Discord notifications (Supabase) * | Your Discord webhook URL and your API key, held so a server job can check your queue every hour | off until you enable it, and nothing is stored before that | Settings → Notifications |
| Send feedback form * | Your note, level, platform, and install age, sent to a private Discord channel and kept so a reply can reach you, plus your API key, which is used to look up the WaniKani username the note is filed under and then discarded rather than stored | only when you submit, and the form needs your API key to send at all | Do not submit |
| Reply notifications (Supabase) * | This browser’s push address, so a reply can reach you when the app is closed, plus your API key to confirm whose it is, which is then discarded rather than stored | off until you accept the browser prompt | Settings → Notifications |
| Reply check * | Your API key, sent to work out whether a reply is waiting for you, then discarded rather than stored | on for every logged-in account, on each app open, each return to a signed-in page, and each time you switch back to the tab | Log out; there is no separate toggle |
- WaniKani API
Your API key, with every request for your WaniKani data
Default: always · Turn it off: Log out
- PostHog analytics
Usage events, session replays, and crash reports, tagged with your WaniKani username and level
Default: on · Turn it off: Settings
- Study history backup (Redis) *
Per-day activity counts and the SRS timeline
Default: on · Turn it off: Settings → Advanced
- Review history (Supabase) *
A per-item record of your reviews
Default: on (same switch) · Turn it off: Settings → Advanced
- Achievement sync (Redis) *
The badges you have earned, with dates
Default: on (same switch) · Turn it off: Settings → Advanced
- Public profile (Redis) *
An aggregate snapshot of your stats
Default: off until you publish · Turn it off: Unpublish
- Discord notifications (Supabase) *
Your Discord webhook URL and your API key, held so a server job can check your queue every hour
Default: off until you enable it, and nothing is stored before that · Turn it off: Settings → Notifications
- Send feedback form *
Your note, level, platform, and install age, sent to a private Discord channel and kept so a reply can reach you, plus your API key, which is used to look up the WaniKani username the note is filed under and then discarded rather than stored
Default: only when you submit, and the form needs your API key to send at all · Turn it off: Do not submit
- Reply notifications (Supabase) *
This browser’s push address, so a reply can reach you when the app is closed, plus your API key to confirm whose it is, which is then discarded rather than stored
Default: off until you accept the browser prompt · Turn it off: Settings → Notifications
- Reply check *
Your API key, sent to work out whether a reply is waiting for you, then discarded rather than stored
Default: on for every logged-in account, on each app open, each return to a signed-in page, and each time you switch back to the tab · Turn it off: Log out; there is no separate toggle
* These sends include your WaniKani API key so the server can verify account ownership - see Your API key.
Any web request also shows the receiving server your IP address and user agent. WaniKani, PostHog, and Vercel (hosting) necessarily see these, as do the hosts the browser loads content from directly: cdn.jsdelivr.net serves the kanji stroke-order diagrams (the request URL names the kanji you view), and NHK and the Wayback Machine serve news images. Wanilog does not log any of it.
Your API key
Your WaniKani API key is stored in your browser's localStorage and sent to api.wanikani.com whenever Wanilog fetches your data. Logging out removes it from your device.
The starred rows above also carry the key. Whenever Wanilog writes to its own server - publishing a profile, syncing achievements, backing up study history or the SRS timeline, storing review history - the request includes the key, and a server function calls api.wanikani.com/v2/user with it to confirm that the WaniKani username it returns matches the one being written to. That check is what stops someone else from claiming /u/your-usernameor writing history in your name. After a successful check the key is stored on Wanilog's server along with your username and level so account issues can be investigated; unpublishing your profile deletes the stored key, and any later verification stores it again. The reply check under Sending feedback is the one starred row that stores nothing: it verifies your key and discards it.
Discord notifications are the exception to that pattern. While they are on, your key is kept so that a job on Wanilog's server can call WaniKani on your behalf every hour; every other flow above uses the key for its ownership check and then leaves the stored copy alone. See Discord review notifications.
The key is never sent to PostHog and never appears in analytics events.
Analytics
Wanilog is a personal side project with limited time, and usage data is what decides where that time goes: which features earn attention, and which pages quietly broke for a subset of users after a release. Events go to PostHog through a proxy at shiba.wanilog.com, and each one is tagged with your WaniKani username and level. That makes the data identifiable rather than anonymous, which is what enables cohort analysis such as tracking engagement by level.
- Pageviews. Pathname only. Query strings and URL fragments are stripped.
- Feature usage. Named events such as "opened a study tool" or "downloaded a share card". Numeric properties are bucketed (for example 10-49 or 50-99) before transmission.
- Clicks. PostHog autocapture records the element type, CSS selector, visible text, and link target of the buttons and links you interact with. The contents of input, textarea, password, and hidden fields are stripped before transmission.
- Web vitals. Page-load timings (LCP, CLS, INP, FCP) used to detect performance regressions between releases.
- Crashes. Uncaught JavaScript exceptions with stack traces of Wanilog's own source, used to diagnose and fix bugs.
- Console logs. Warnings and errors that Wanilog prints to the browser console, captured to surface problems in production. This capture stays on even when analytics are turned off in Settings; the network-level block below is the only reliable way to stop it.
- Session replays. PostHog records DOM-level interactions (clicks, scrolls, navigation, and timing) using rrweb. All form inputs, including the "Can I read this" textarea and the API key field, are masked before recording. Replays are retained for 30 days.
To turn analytics off, open Settings and disable Help improve Wanilog. The change takes effect immediately and persists across sessions. The console-log capture is the one thing that toggle does not reach: for a complete block, any content blocker that drops requests to shiba.wanilog.com, such as uBlock Origin, Brave Shields, NextDNS, or an entry in your hosts file, stops every transmission, and the rest of the app keeps working.
Cloud backup and review history
One shared switch covers everything Wanilog stores about your studying on its own server. It is on by default, and it appears twice in Settings → Advanced - as Study history backup and as Achievement sync - but both toggles flip the same underlying consent: turning either one off stops all of it. While it is on, everything below is stored under your WaniKani username:
- Study history backup. Your per-day activity counts (lessons, promotions, demotions, and completed reviews per date), so the heatmap and streaks survive a browser-storage clear and follow you across devices, plus one row per day recording how many of your items sat in each SRS stage grouping, read back by the SRS-over-time chart on
/reviews. Sent via/api/activityand/api/srsto Upstash Redis. Counts only: this store holds no per-item detail. - Review history. A per-item record of the reviews Wanilog observes: which item, when, and how its SRS stage moved. The WaniKani API no longer provides review-by-review history, so this record is what powers the day-by-day drill-down behind the heatmap. Sent via
/api/loomto Supabase. Aggregated, anonymized statistics derived from it, such as community rankings of which kanji are demoted most often, may be shown publicly; they never identify an individual user. - Achievement sync. The badges you have earned (badge id plus the date), so your badges follow you across devices. Sent via
/api/achievementsto Upstash Redis.
Turning Study history backup off deletes the stored activity counts, the SRS timeline, and the review history from the server, not just future writes. The badge record is not deleted by the toggle; email the address at the bottom to have it removed.
Public profiles and leaderboards
Publishing is opt-in: nothing exists until you tap Create shareable link on the /share page. Publishing sends an aggregate snapshot of your stats to /api/profile, which stores it in Upstash Redis: your username, current and goal level, account start date, projected finish date, your SRS distribution (counts at each stage), kanji unlocked and learned counts, JLPT / Joyo / frequency coverage percentages, lifetime accuracy and review count, per-level durations, one representative kanji per level, any tagline you set, and - when you have study history - your activity heatmap (per-day lesson / review / burn counts for the past year) plus your streaks. It does not contain your API key or any review-by-review history. Once a profile exists it refreshes automatically as you use the app, so the public copy tracks your progress.
Profiles are published at /u/your-username, listed on the public leaderboards, and included in the sitemap, so search engines may index them. Stored profiles persist indefinitely; there is no automatic expiry. Re-publishing overwrites the snapshot, a toggle in Settings removes you from the leaderboard rankings, and the email at the bottom gets everything deleted.
Discord review notifications
Opening Settings asks /api/notify/me whether notifications are on for you. That request carries your API key, which is checked against WaniKani to prove the account is yours; nothing from it is kept.
Pasting a Discord webhook URL is what begins the storage. It sends that URL and your API key to /api/notify, which holds both in Supabase and sends one test message through the webhook on the spot. From then on, /api/notify/runreads your key once an hour, asks WaniKani how many lessons and reviews are waiting, and posts to your webhook when the number has gone up. It runs on a schedule on Wanilog's server, so it keeps happening with the app closed and your device off. If review history sync is on, the hourly check also reads how fast you got through your recent reviews, so the message can estimate how long the queue waiting for you will take. That estimate is only ever a line in the message. Send a test in Settings posts one of these messages on demand: the press sends your API key to /api/notify/test, which checks it against WaniKani, posts into your channel, and stores nothing.
Each message, the test one included, carries the waiting counts, how the waiting reviews split across radicals, kanji, and vocab, when your next review is due, your current level and how many kanji it still needs, how many items you hold at each SRS stage, and a chart of the reviews arriving over the following day. It lands in whichever Discord channel the webhook belongs to, readable by everyone with access to that channel. Your quiet hours, your time zone, and which of lessons and reviews you asked for are stored next to the key.
Turn off in Settings deletes the whole record, key and webhook URL together. If delivery keeps failing, notifications pause rather than turn themselves off, and the stored key stays with the paused record until you turn them off yourself. The exception is a key WaniKani itself rejects, which is dropped as soon as it stops working. Turning notifications back on stores a fresh copy: Enable verifies your key again, and on a record paused for a rejected key or a run of failed deliveries there is no webhook to paste for it.
Neither the delete nor an automatic pause reaches the separate troubleshooting copy of your key described under Your API key. Turning notifications off verifies your key on the way, so that copy can be rewritten seconds before the record is deleted. Unpublishing a public profile is the one thing that removes it, so if you have never published a profile, email the address below to have it deleted.
Sending feedback
The Send feedback form (the ? in the navbar, also reachable from Settings and the command palette) posts your note to a private Discord channel via /api/feedback, along with your level, platform, and how long ago you installed. The note and those same details are also kept in Supabase, with no expiry, so a reply can reach you later.
That submit sends your API key, and the form will not send without one. Your username is never taken from your browser: the server asks WaniKani who the key belongs to and files the note under the name it gets back. WaniKani handles are public, so a name your browser simply asserted would let anyone open a thread as you and be answered as you. The key is used for that one lookup and discarded; this route does not keep it. If WaniKani cannot be reached, the note is not sent and the form asks you to try again.
After a note is sent, Wanilog offers to notify you when the reply arrives. Accepting asks your browser for notification permission and registers this one browser with /api/push: what is stored is the address your browser's push service issued, the keys needed to encrypt a message only that browser can open, and which language to write it in. Your API key is sent once, to confirm which account the browser belongs to, and is discarded; sending a notification needs nothing from WaniKani afterwards. The notification carries the first line or so of the reply, because it renders on a lock screen. Turn it off in Settings, or through your browser's own site settings, and the record is deleted.
The app checks whether a reply is waiting through /api/messages. To work out which thread is yours it sends your API key to check your username against WaniKani, then discards it: like the submit above, and unlike the cases further up this page, this one does not keep the key. The check runs for every signed-in account, whether or not you have ever sent feedback: each time you open the app, each time you return to a signed-in page from a public one like this one, and each time you switch back to the tab after leaving it. Replying goes through the same route, so it sends your key the same way; unlike the feedback form it attaches no level, platform, or install age. Marking a reply read when it appears uses that route too, so an app open that shows you one sends your key twice, or three times if you answer.
Server plumbing
The remaining server routes carry no personal data. /api/nhk proxies NHK Easy News headlines for the reading-coverage page, and /api/wk-asset proxies WaniKani's content CDN so subject images and audio can be cached for offline use; neither ever sees your API key. /api/geo returns the approximate location Vercel infers from your IP address (country code, city, coordinates) to your browser tab, where the landing page draws its globe arc; the response is not stored, logged, or shared. /api/mentions runs on a schedule and watches the WaniKani community forum for mentions of Wanilog; it reads public forum posts and touches nothing about you.
What Wanilog does not do
Wanilog does not sell your data, show ads, or use Google Analytics, the Meta pixel, ad networks, or data brokers, and your data is never used to train an AI model. The Can I read this analyzer never transmits what you type into it. Guide articles embed a handful of YouTube videos in click-to-activate, privacy-enhanced mode (youtube-nocookie.com): nothing is requested from YouTube or Google unless you press play. Demo mode is fully silent: no events fire while it is active.
Removing your data
Email privacy@wanilog.com to have everything stored about you deleted, to get a copy of what is held, or to correct anything inaccurate. Wanilog is operated as a personal side project; the same address answers any other privacy question.