Your data
What TokenRPG collects, what it keeps and for how long, and who can see it. Every list below is read from the code that does the collecting, and an automated test fails if the code and the list part company.
You can change who sees what in Settings → Privacy, delete your account at Settings → Security or on the Delete my data page, and read the privacy policy and the terms.
What your computer sends
A small script on your computer (the collector, version 13) reads the usage counts Claude Code keeps in your own log files and uploads them to this site: at most every 2 minutes while you work, once when a Claude Code session starts or ends, and whenever you run it yourself. This is everything in an upload, field by field:
Sent with every upload
These travel in the request's headers.
Authorization- Your upload token, which says whose numbers these are. Why: So the server can tell who the upload belongs to. It is not your Claude login.
User-Agent- The collector's name and version, such as tokenrpg-collector/13. Why: So we can tell which versions are out there.
Content-Type- That the upload is JSON. Why: Plain plumbing.
For each day
One set for each of the last 28 days, under the day's date. Every upload sends them all again, so a missed upload fixes itself. The first upload (step 2 of Connect, --days 0) sends every day still in Claude Code's logs, which usually keep about a month.
days.<date>.input- Input tokens that day, added up over every message. Why: Part of the day's total, which is your XP.
days.<date>.output- Output tokens that day. Why: Part of the day's total, which is your XP, and the words figure on Activity.
days.<date>.cache_write- Cache-write tokens that day. Why: Part of the day's total, which is your XP.
days.<date>.cache_read- Cache-read tokens that day. Why: Part of the day's total, which is your XP.
days.<date>.messages- How many replies Claude gave that day. Why: For the messages chart on Activity.
days.<date>.models.<model>- Tokens that day for each model, under the model's name. Why: For the Models & token mix card, your class, the Polyglot and All-rounder achievements and the Polyglot title.
days.<date>.hours.<hour>- Tokens that day for each hour (0 to 23), by your computer's clock. Why: For the Hours of day card, the Night Owl, Early Bird and Night and Day achievements, the Owl and Lark titles, and the live map.
About the machine
Once per upload, for each Claude folder.
device.id- A scrambled code made from your computer's own id, your home folder and the Claude folder. It can't be turned back into any of them. Why: To tell your computers apart, so one computer is counted once however often it uploads.
device.label- Your computer's network name (its hostname, up to the first dot), followed by the Claude account folder's name when it isn't the usual ~/.claude. Why: So you can tell your machines apart in Settings. Only you and the admins see it.
hooks- Which of our hooks are set up in that Claude folder, as event names only (such as Stop). Why: So Settings can tell you how often that machine updates, and whether to run step 3 again.
client- The collector's version, such as tally_tokens/13. Why: So we can tell when a copy is out of date and say so in Settings.
os- Whether the computer is a Mac, Linux, Windows (WSL) or Windows. Nothing finer. Why: Shown to you in Settings, and lets an admin write to players on one kind of computer.
Your plan
A few named entries from Claude Code's own settings, if it has them.
plan.organizationType- The kind of Claude account, from Claude Code's own settings file (~/.claude.json). The collector reads that whole file on your computer and keeps only the three plan entries listed here; nothing else in it leaves your computer. Why: To work out your plan badge (Pro, Max and so on). Only the plan's name is stored, not this text.
plan.organizationRateLimitTier- Your plan's rate-limit tier. Why: To tell Max 5x from Max 20x. Only the plan's name is stored.
plan.subscriptionCreatedAt- When your subscription began. Why: To show how long you have had your plan. Only the date is stored.
plan.subscriptionType- On Linux, the same plan information from .credentials.json, the file that also holds your Claude login. The collector reads that file on your computer and keeps only these two entries; your login tokens in it are never sent or stored anywhere. Why: The same plan badge, where the first file doesn't have it.
plan.rateLimitTier- On Linux, your rate-limit tier from that file. Why: The same badge.
Sent by older versions only
plan.billingType- How the plan is paid for, from Claude Code's settings file (~/.claude.json). Never used. Version 13 stopped sending it; when an older copy still sends it, the server drops it and stores nothing from it.
What the fields can say
- The kind of computer is one of Mac, Linux, Windows (WSL), Windows.
- The hooks are some of SessionStart, SessionEnd, Stop, PostToolUse: our upload commands, by event name only.
What is never sent
- Your prompts, or anything Claude wrote back.
- Your code or the contents of any file.
- The names of your files or folders (v12 stopped reading even the folder you work in; older versions sent its last name, and every stored one was deleted).
- Your Claude login or its tokens (on Linux the collector opens the file they are in, to read two plan entries, and sends only those).
- Your name, your email address or your password. The collector doesn't have them.
What you give us on the site
- Your email address
- At sign-up. For your verify link, password resets and other account emails, and the game and service emails in Settings → Emails: challenge results, "a friend challenged you" and service notices are on until you turn them off; news and the monthly recap are off until you turn them on.
- A password
- At sign-up. We keep only a one-way hash of it.
- A handle
- At sign-up, and when you rename. It is public: it is your name on the Stack.
- A country (optional)
- At sign-up or in Settings. It shows as a flag by your name, and feeds the world map's count.
- A picture (optional)
- Settings → Profile. A file on the server, shown to anyone wherever your handle is. When you upload it we remove what's hidden inside it (where and when a photo was taken, the camera, any comments), so only the picture is kept, and which way up it goes.
- A daily quest
- Settings → Profile. A number for your progress bar.
- Your privacy choices and email choices
- Settings → Privacy and Emails.
- Crossroads picks
- When your hero reaches a fork in the road and you choose.
- Friends, challenges and the sword-taps (⚔) you give
- As you use Friends and the feed.
- Feedback you send
- The box at the foot of each page: your message, the page, your browser, and for each of your machines its name, collector version, plan and last upload time.
- A friend's email address, name and note
- If you invite a friend from Settings. The address is checked and used for that one email.
- Reports you make
- The Report link on another player's profile: who you reported, the reason you picked and your note. Only the admins see it; the player isn't told who reported them, or that anyone did.
- Two-factor login (optional)
- Settings → Security. Your authenticator app's key, sealed, and ten recovery codes, kept only as hashes, until you turn it off.
What we hold, and for how long
This is the database, table by table, with every column named. The person who runs the server can open the database itself, so everything listed under what we hold is readable to them. That is true of any website; we say it so you don't have to guess.
Download my data: Settings → Security gives you what we hold on you, table by table as below, and your picture, as one file; what it leaves out (secrets such as your password's hash, and what other players keep private) is named in it, each with its reason.
users
One row per account: who you are and your settings.
How long: While your account exists. Deleting your account removes it.
idseedcreated- Your account number, a random number that seeds your hero's story, and the day you joined.
email- Your email address.
email_statusemail_status_atemail_status_event- Whether our email service told us your address bounced, or that you reported us or unsubscribed: which, and when.
pw_hash- Your password as a scrypt hash. The password itself is never kept.
handleavatarcountrydaily_goaltitle- Your handle, your picture's file name, your country, your daily quest and the title you wear.
upload_token- Your upload token, kept as it is because the server must recognise it on every upload. Settings → Security can replace or revoke it.
is_admin- Whether you are an admin.
last_uploadupdates_seenalerts_seen- When you last uploaded, the newest entry on Updates you have seen, and when you last opened the bell (for players who joined before 23 Oct 2026, starting at that date).
show_planvis_profilevis_tokensvis_modelsvis_hoursvis_planvis_machinesvis_leaderboardsvis_livecount_on_map- Your choices in Settings → Privacy.
email_resultsemail_challengedemail_recapemail_newsemail_service- Which emails you have asked for.
verifiedsession_gen- Whether you have verified your email, and a number that logs your other browsers out when you change your password or press Log out everywhere.
tour_done- Whether you have finished or skipped the guided tour, so it starts once (players who were already here when the tour was added are marked as done).
usage_gen- A counter that goes up whenever your usage, crossroads choices, duels or challenges change, so the site knows when to work out your titles and achievements again.
totp_secrettotp_pendingtotp_ontotp_last_steptotp_since- Only if you turn on two-factor login (any player may; admins must): the authenticator app's key, sealed so a copy of the database alone can't read it, whether it is on and since when, and the last code used, so no code works twice. Turning it off empties them.
kindsamples_onsample_profile- Whether the row is a real player or a made-up sample (samples exist only for admins to look at), and an admin's switch to see them.
avatar_hiddensuspended_atsuspended_reason- Whether an admin hid your picture, and whether an admin suspended the account: since when and why.
vis_region- Unused: a privacy row that was removed.
vis_anon- Unused: a privacy row that was removed.
vis_projects- Unused: a privacy row that was removed.
region- Unused and emptied on every start: the county or state some players once picked.
usage
One row per machine per day: the day's token counts, by type, model and hour.
How long: While your account exists, or until you remove that machine in Settings → Your machines.
user_iddevice_iddayinputoutputcache_writecache_readtotalmessagesmodelshoursupdated- The numbers listed above under what your computer sends, and when the row was last written.
projects- Always empty: project names (sent by versions before 12) were deleted.
devices
One row per machine: its label, plan, collector version, hooks and kind of computer.
How long: While your account exists, or until you remove the machine.
user_ididlabelplanplan_sinceclienthooksos- What the upload says about the machine.
first_seenlast_seen- When the machine first and last uploaded.
uploads
The timing of recent uploads: when each day's total rose, and by how much.
How long: 7 days, then it is forgotten.
user_iddevice_idtsdeltadaytotal- The time of an upload and how far the day's tokens rose. It is how the live map knows when you were working.
choices
Your crossroads picks.
How long: While your account exists. Deleting your account removes it.
user_iddaypick- The day and what you chose.
friends
Friend requests and friendships.
How long: While your account exists. Deleting your account removes it.
requesteraddresseestatuscreated- Who asked whom, whether it was accepted, and when.
challenges
7-day challenges between friends, one side against another.
How long: Kept while anyone who played in it has an account (one that never started: anyone picked who said yes or hasn't answered), then deleted. If you delete yours, your place in it goes with you (who threw it reads as nobody if it was you), and its result and the other players' spoils stay. Before it settles, your tokens that week stay in it, counted for your side, until it settles. Two exceptions while it is still under way: on Beat your normal you drop out of your side's average instead, and if nobody else on your side is left, it is called off and your tokens go. Once settled, a side with nobody left in it loses its score; a team side's score stays while one of its players does, since it is the result they earned.
idchallengeropponentstatusstartendcreateddecided_at- Who threw it (and side b's first player), the dates, how it stands, and when it started or was called off.
scoringresultscoressettled_at- How it is scored (Most tokens or Beat your normal), and once it settles, frozen: which side won, each side's score and each player's tokens and figure that week, and when. Before it settles, the tokens that week (and for Beat your normal, the normal) of anyone who deleted their account while in it. Before and after, how many on each side deleted their account (a number, no names). For a day after the site is restored from a backup, the day it may settle again.
notifiedmail_error- Whether the result emails went out, and why one didn't.
challenge_members
Who is in each challenge: one row per player picked.
How long: While your account exists, and the challenge does. Deleting your account removes your rows.
challenge_iduser_idsidestatusresponded_at- Which challenge, which side, whether you said yes or no (or were left out to keep the sides even), and when.
baseline- Beat your normal only: your average day played over the 30 days before it started, frozen then.
bonus- Once it settles, frozen: the spoils of war you won as XP (5% of your own tokens that week), 0 if your side lost or drew, blank for a challenge settled before team challenges came.
duels
The duel your hero fights for each level it reaches.
How long: While your account exists. If your opponent deletes theirs, the duel stays, with the opponent blank.
user_idleveldayopponent_idwoncreated- The level, the day, who it was against, and who won.
reports
Reports players made about other players, from the Report link on a profile.
How long: While the reported player's account exists. If the person who made a report deletes their account, the report stays, with who made it blank.
idreporter_idtarget_idreasonnotecreated- Who made the report, about whom, the reason picked, the note typed, and when.
statusclosed_byclosed_at- Whether an admin has dealt with it: which admin, and when.
mod_log
What admins did on Admin → Players: a rename, a hidden picture, a suspension, a deletion, a closed report.
How long: Kept. When the player's account is deleted the line stays with who it was about blank and its detail emptied.
idadmin_idsubject_idactionat- Which admin did what to which account, and when.
detail- The old and new handle of a rename, the admin's reason, or a closed report's number.
kudos
The sword-taps (⚔) you gave to feed events.
How long: While your account exists. Deleting your account removes it.
user_idevent_keycreated- Who tapped which event, and when.
invites
Email invites you sent, and those sent to your address.
How long: While your account exists. The link in the email works for 30 days.
idinviteremailtoken_hashnamenotestatuserrorjoined_usercreated- Your friend's email address, the name and note you typed, whether it was sent (an address that already has an account is recorded but never sent anything), who joined through it, and the invite link as a SHA-256 hash only.
feedback
Messages you sent from the feedback box.
How long: While your account exists. Deleting your account removes it.
iduser_idkindmessagepagebrowsercontextmailerrorcreated- Your message, which kind it was, the page and browser it came from, each of your machines' name, collector version, plan and last upload time, and whether the email to the admins went out (or wasn't, past the daily limit on those emails).
password_resets
Password reset links, as SHA-256 hashes.
How long: The link works for 1 hour (24 hours if an admin makes it) and once. A used or expired one is cleared out by the same tidy-up as the links below, at most once every 1 hour.
token_hashuser_idexpiresusedcreated- A hash of the link, whose it is, when it expires, and whether it has been used.
email_links
Verify, change-of-email, undo, delete-my-data and two-factor reset links, as SHA-256 hashes.
How long: A verify link works for 24 hours, a change link for 24 hours, an undo link for 7 days, a delete-my-data link for 1 hour, a two-factor reset link for 1 hour. A used or expired one is cleared out by a tidy-up that runs at most once every 1 hour. A verify link of an account that hasn't verified waits until it does or is deleted (7 days).
token_hashuser_idpurposeemailinvite_idexpiresusedcreated- A hash of the link, whose it is, what it does, the email address it concerns, and its dates.
recovery_codes
Only if you turn on two-factor login: its ten recovery codes, as SHA-256 hashes.
How long: Until you make new ones (they replace these) or turn two-factor off. Deleting your account removes them.
user_idcode_hashusedcreated- Whose codes they are, a hash of each, and whether it has been used.
rate_hits
Counters for the limits (sign-ups, reset requests, wrong passwords and codes, uploads per hour, new machines, invites, feedback emails, reports, downloads of your data, and the once-a-day email when someone types wrong two-factor codes after your password). Wrong logins are counted here too.
How long: 24 hours, then deleted.
bucketuser_idip_hashat- Which limit, which account, your IP address (or, for a login to no account, what was typed) scrambled with a secret key, and the time. It can't be turned back into the address without that key, which is kept with the database (so whoever has both could test every address).
mail_events
What our email service told us happened to mail sent to you (bounced, reported as spam, unsubscribed).
How long: While your account exists. Deleting your account removes it.
iduser_ideventmessage_idreasoncreated- The event, the mail's id and the reason given.
mail_queue
Whether an admin's news or service email reached you.
How long: While your account exists. Deleting your account removes it.
idcampaign_iduser_idstatuserrorclaimed_atdone_at- One row per player per email: sent, skipped or failed, and when.
mail_campaigns
Each news or service email an admin sent.
How long: Kept. It holds the email's text and how many got it, not who.
idadmin_idkindsubjectbodyaudiencesitetotalleft_outcreated- The subject and text, which group it went to, and the counts.
app_settings
Site-wide switches, such as the daily cap on invite emails.
How long: Kept. No personal data.
keyvalue- A setting's name and value.
featured_projects
A feature removed in October 2026.
How long: Empty: emptied on every start.
Columns, all unused: id user_id folder title url blurb created.
project_updates
A feature removed in October 2026.
How long: Empty: emptied on every start.
Columns, all unused: id project_id body created.
Outside the database
- Your picture
- A file on the server's disk, named in users.avatar, with what was hidden inside it removed when you uploaded it (where and when a photo was taken, the camera, comments). Until you replace it or delete your account.
- Your login
- A cookie in your browser called session, signed by the server. It holds a security token for the site's forms and, once you log in, your account number and when you logged in. Logged out, you get one too as soon as a page has a form (logging in, signing up): then it holds only the token. The server keeps no list of logins. A login lasts 30 days from when you log in (12 hours for an admin), however often you use it. Log out ends it in that browser; Settings → Security → Log out everywhere ends every login to your account at once.
- A known-browser cookie
- A cookie called known, set when you log in: your account number, a random value and a signature, so the site knows this browser has logged in to your account before. It can't log anyone in. It matters only when someone has been guessing your password: then logging in from a browser without it needs the human check too. 365 days from your last login. Logging out leaves it; clear it in your browser like any cookie.
- Two small choices
- The map's last view (Friends or Global) and the last period you looked at on a profile are kept in your browser's own storage. They never reach the server. Until you clear your browser's storage.
- The server's request log
- A plain log of each request (time, page address, result, size and browser name) kept by the server, outside the database. A page address can name a player, as /u/<handle> does. It holds no IP address, no account and not the page you came from. Secret links in it, and what an admin typed to search for a player, are blanked. Until 30 MB of newer lines have been written (3 files of 10 MB), or the site is next updated, whichever is first.
- Wrong logins
- Rows in rate_hits above. Each wrong password leaves one with your IP address scrambled with a secret key, and one for each account it was checked against, each with its time. A login by handle is checked against one account; a login by email address always against three (the account with that address and up to two sign-ups waiting on it), and where fewer exist, what was typed stands in, scrambled the same way. Those per-account rows stop at 10 in 15 minutes. 24 hours, then deleted.
- The deletion list
- A file beside the database, deletions.ledger: one line per deleted account, holding its account number, when it was made, the random number that seeded its hero, and the day it was deleted. No email, handle or anything else about you. Kept, so that restoring the database from the server's snapshots doesn't bring a deleted account back: every start deletes again any account on it. It sits beside the database, so a rebuild from the second copy has that night's list (see What stays after you delete, in the privacy policy).
- Google Analytics cookies
- Cookies called _ga and _ga_ plus an id, set in your browser only if you press Accept on a public page while logged out. They hold a random id so Google can tell visits apart; nothing about your account. Your answer is kept in your browser's own storage as tokenrpg.consent and never reaches the server. Up to 365 days after your last visit (Google renews them on each visit). Reject, or Cookie settings in the footer, removes them from that browser.
Backups
The server is backed up. After you delete your account, a copy of your data can stay in a snapshot on the home server for up to 8 weeks, and in its nightly copy on a second machine for up to 6 months (checked 23 October 2026). A restore from the hourly, daily or weekly snapshots replays the deletions; if the home server itself were lost and rebuilt from the second copy, deletions from the last day before the loss could come back, and we would delete them again on request. Our email service keeps its own sending logs under its own policy. More in the privacy policy.
Who sees what
You always see all of your own data. Everyone else sees only what these rows allow. Each is a level: Only me, Friends, TokenRPG users (anyone logged in) or Everyone. A row can never be wider than "Who can open your profile". What a person may not see is left out of the page itself; it is not hidden with styling.
- Who can open your profile
- Anyone else sees only your name and picture. Rows below can't be wider. New players start on Everyone.
- Token numbers
- Every token and XP figure: totals, charts, the activity grid's sizes, bugs slain. Level, bosses, loot and streak stay visible. New players start on Everyone.
- Models & token mix
- New players start on Friends.
- Hours of day
- New players start on Friends.
- Plan badge
- On your profile and on leaderboards. New players start on Everyone.
- Machines
- How many machines you've connected. New players start on Everyone.
- Leaderboards
- Whether you appear on boards. Never wider than Token numbers, because boards show your tokens. New players start on Everyone.
- Live activity
- Who sees you on the live map. Only people your Hours of day row reaches see you there, because the map shows when you code. New players start on Friends.
- Count me on the world map
- Count me in my country's number on the public world map. Only the number of players is shown, only when 3 or more count, and only players whose profile is open to Everyone are counted. On unless you turn it off.
Only you, and the admins
Your email address, your machines' names and kinds, your feedback messages, the reports you make and your email choices are not on any privacy row. Nobody but you and the admins can see them. Your password is never shown to anyone, and your upload token is shown only to you.
What an admin can see and do
- Every player's handle, email address, country, join date and last upload.
- Every player's level, total tokens, tokens in the last 7 days, average per active day, number of machines and friends, plan badge, and who invited them. Not one player's day-by-day numbers.
- A chart of the whole site's tokens per day, everyone added together.
- Everything anyone sends through the feedback box, with the page, the browser and each machine's name, collector version, plan and last upload time.
- The email addresses people invited, who invited them, and what happened to each invite.
- The whole site's search and visit figures from Google (searches, pages, countries, devices, where visits came from) and how many accounts were made each week. Nothing about one player.
- Which players match a group (kind of computer, collector version, plan, country, activity) when writing to players, and which of them an email went to.
- Which players' addresses our email service says can't be reached (bounced, blocked, reported as spam or unsubscribed), and since when.
- Every account's handle, email address, join date, whether it is verified, last upload, open reports and whether it is suspended; and for one account, the reports made about it, who made them, and what admins did.
No admin page shows a password (not even its hash) or an upload token. Admins can:
- Make a one-time password reset link for any account (it works for 24 hours). Whoever opens it can set that account's password, so it is a way in to the account; admins use it only to help someone who is locked out.
- Write to players: news only to those who turned it on, service notices to the rest, from Admin → Email.
- Clear the mark on an address our email service said can't be reached, so mail goes to it again.
- Rename an account, hide its picture, suspend it or delete it, from Admin → Players, when its handle or picture is abusive, it sends spam or it is a fake account. A rename and a suspension each email the player, with the reason. A suspended account can't log in or upload and is hidden everywhere, counted nowhere and sent no email but those notices and the account emails it asks for (a Delete my data link). Nothing is deleted, but a challenge still waiting to be accepted is cancelled; lifting the suspension puts the rest back. Admins can't do any of this to another admin.
- Look at any profile, as any other player would: your privacy settings apply to admins too. A suspended account's profile is the exception: only admins can open it, and they see what they would see if it weren't suspended.
Admin → Email can pick players by the kind of computer (Mac, Linux, Windows (WSL), Windows), the collector version, hooks, plan, country and how recently they uploaded.
Outside services
Only these, as of today:
- Brevo
- Sends our email (verify links, password resets, results, news). Gets: Your email address and the email's text. It keeps its own sending logs. Their policy
- Cloudflare
- Carries the traffic between you and the site, runs the human check (Turnstile) on forms that send email, and handles our domain names. Gets: Your IP address and the pages you ask for, as any network does; the check also sees signals from your browser. When you give an email address we ask its DNS service whether the part after the @ can receive mail (the part before the @ is not sent). Their policy
- Google Search Console
- Tells us how people reach the public pages from search. Gets: Search statistics about the site. It gets no player data from us. Their policy
- Google Analytics
- Counts visits to the public pages. It loads only for a visitor who is not logged in and presses Accept. Gets: Your IP address, your browser, the page you open and the page you came from, and a random id kept in your browser's _ga cookies. Nothing from your account: it never loads when you are logged in. Their policy
The only analytics is Google Analytics, on the public pages, for a visitor who is not logged in and presses Accept. The server's request log notes each page asked for, but not who asked: no IP address, no account. Tally Digital's own sub-processors page lists the services it uses across its products.
Check the collector you run
The collector is a single Python file, tally_tokens.py. Its source is public at
github.com/Jabulani27/tokenrpg-collector, and the copy this server hands out at
/collector.py is byte-identical to it. Its SHA-256:
df40fa36a93a726447c8436506b5a19fe144bae840709d6f063280c3638477e9
To check the copy on your computer, run one of these and compare:
Linux or WSL
sha256sum ~/.local/share/tokenrpg/tally_tokens.py
macOS
shasum -a 256 ~/.local/share/tokenrpg/tally_tokens.py
A copy that is older than the one this server serves updates itself to it the next time it uploads, so an old copy won't match until then. The script has no other way to change what it does.