Export your PlayStation Network play history to CSV/JSON and build an LLM-ready taste profile (with prompts), entirely on your machine.
Project description
psnstats
Export your PlayStation Network play history to CSV/JSON and build an LLM-ready taste profile (with prompts), entirely on your machine.
psnstats pulls every PS4/PS5 title you've played, with real playtime and play counts, into plain .csv and .json files you own. Add --analyze and it also scores each game, derives five player traits, and writes a preferences.json you can hand to an LLM to get recommendations that actually fit how you play.
Your NPSSO session token is only ever sent to Sony. Nothing else leaves your machine.
What it looks like
======================================================================
ANALYSIS REPORT
======================================================================
fetch ok : 131 games from API
export ok : 14 games kept
(skipped 3 off-platform, 114 under threshold)
analyze ok : 14 games
----------------------------------------------------------------------
TOP 10 GAMES (by enjoyment)
----------------------------------------------------------------------
# Title Sys Score Hrs Plays Last
----------------------------------------------------------------------
1 Elden Ring PS5 91.2 120 340 2026-07
2 Bloodborne PS4 79.2 62 90 2026-05
3 Stardew Valley PS4 79.0 90 180 2026-06
4 God of War Ragnarok PS5 76.9 45 60 2026-06
5 Cyberpunk 2077 PS5 74.5 80 110 2026-05
6 Hades PS5 73.2 38 210 2026-07
7 Disco Elysium - The Final Cut PS5 71.3 24 20 2026-06
8 Returnal PS5 65.0 30 75 2026-06
9 Tetris Effect PS4 60.4 12 140 2026-07
10 Untitled Goose Game PS4 58.0 6 12 2026-05
----------------------------------------------------------------------
PLAYER TRAITS
----------------------------------------------------------------------
Snackable [##############------] 71.4 (sessions/hr: 2.10 median)
Marathon [############--------] 64.3 (hrs/session: 0.5 median)
Completionist [##########----------] 50.0 (completion: 58% avg)
Friction Tol [###-----------------] 17.9 (early: 14%, late: 29%)
Variety [###################-] 95.0 (entropy: 1.00)
----------------------------------------------------------------------
PLAY STYLE
----------------------------------------------------------------------
Session style : mixed
Commitment style : mixed
Platform recency : PS5 66% / PS4 34%
(Example above is synthetic data; your own run reflects your library.)
Why
The most-starred "PSN API" projects — psn-api, psn-php, and psnawp (which this is built on) — are developer libraries: they hand you raw endpoints, not files. The only end-user tools scrape a third-party website. Nothing shipped turns your library into files you own, and nothing anywhere computes a taste profile from it.
psnstats is the first end-user tool on Sony's own API with playtime export, multi-format output, delta compare, and a taste-analysis layer.
- You own the files. Exophase and PSNProfiles show your stats on their website.
psnstatsgives you.csvand.jsonon disk to keep, diff, and feed to other tools. - Playtime and taste. Plenty of scrapers can list your trophies. Nothing else turns your actual playtime into an enjoyment model and a portable taste profile for an LLM.
- Local-first. No account, no server, no telemetry. Your NPSSO token is sent only to Sony's own API.
It deliberately skips the social surface (friends, presence, messaging, search) — that's what the libraries are for. This is a tool, not a wrapper.
Quickstart
Install with pipx (isolated) or pip:
pipx install awesome-psnstats # console command is: psnstats
Get your NPSSO token (a session cookie):
- Log in to playstation.com in your browser.
- In the same browser, open https://ca.account.sony.com/api/v1/ssocookie.
- Copy the 64-character
npssovalue from the JSON.
Run it:
export PSN_NPSSO="paste_your_token_here"
psnstats --analyze
That writes ./psn-export/ with your library CSV, a JSON export, and preferences.json.
The taste model
With --analyze, every game gets an enjoyment score (0-100), a weighted blend of four signals:
enjoyment = 0.35 * playtime (log-scaled)
+ 0.25 * recency (90-day half-life decay)
+ 0.20 * completion (neutral 50 without --trophies)
+ 0.20 * replay (play count + long-session bonuses)
Two abandonment penalties then apply: -15 if you bounced early (under 20% complete after 3+ sessions) and -10 if you stalled late (10+ hours in, under 40% complete). Completion signals require --trophies; without it, completion goes neutral.
From the per-game scores it derives five player traits (each 0-100):
- Snackable — do you play in short, frequent bursts?
- Marathon — or long single sittings?
- Completionist — how far into games do you push?
- Friction tolerance — do you stick with hard/slow games or drop them?
- Variety — how spread across platforms/kinds of games are you?
And an agent_features block: a preferred session style, commitment style, platform recency split, and plain-language positive/avoid signals — plus the exact weights and thresholds used, so an LLM can reason about why.
The prompts
preferences.json is designed to be pasted straight into a chat with an LLM. Four starters:
Get recommendations:
Here is my PlayStation taste profile as JSON. Based on the traits, enjoyment scores, and positive/avoid signals, recommend 5 games I haven't played that fit how I actually play — and for each, say which signal it matches.
{ ...paste the contents of preferences.json... }
Triage your backlog (paste library.csv too):
Here are my taste profile and full play history. Which games I started but didn't finish are worth going back to, and which should I officially drop? Use my friction tolerance and abandonment signals to justify each call.
Buy advice:
Here is my taste profile. I'm considering buying . Predict how likely I am to actually finish and enjoy it, citing the specific traits and signals that support the prediction. Be honest if it matches my avoid signals.
Rank your wishlist (run with --wishlist, paste wishlist.json too):
Here are my taste profile and my store wishlist. Rank the wishlist by how likely I am to actually play and finish each game, not by hype. Flag anything that matches my avoid signals, and tell me which one to buy next and which to quietly remove.
The filename stays stable (never dated), so you can point a tool or agent at ./psn-export/preferences.json and re-run monthly to keep it fresh.
CSV schema
With --analyze, psn_library_<date>.csv has 12 columns:
| Column | Meaning |
|---|---|
title |
Game name |
system |
PS4 / PS5 / OTHER |
playtime_hours |
Total hours played (float) |
play_count |
Number of sessions |
last_played |
Date last played (YYYY-MM-DD) |
enjoyment_score |
0-100 blended score |
completion_ratio |
0-1 trophy completion (blank without --trophies) |
recency_days |
Days since last played |
hours_per_session |
Marathon signal |
sessions_per_hour |
Snackability signal |
early_abandon |
Bounced early (bool) |
late_abandon |
Stalled late (bool) |
Without --analyze, you get a leaner base library CSV (title, ids, playtime, plays, last played).
Flag reference
Authentication (precedence: --npsso > --npsso-file > $PSN_NPSSO)
--npsso TOKEN— pass the token inline--npsso-file PATH— read from a file (default probe:~/.config/psnstats/npsso;chmod 600it)
Scope
--user ONLINE_ID— export another account's public library instead of your own--platforms LIST— comma list ofps4,ps5,other(defaultps4,ps5)--min-hours N— skip titles under N hours (default1; use0for a full dump)--limit N— stop after N kept titles (handy for a quick test)--wishlist— also export your store wishlist towishlist.csv/wishlist.json(own account only; can't combine with--user)
Enrichment
--trophies— fetch trophy completion (fills completion + abandonment; adds ~80 requests on a 400-game library)
Analysis
--analyze— compute the taste profile (default: off)--compare PATH— diff this run against a previouspreferences.json(implies--analyze)
Output
--output DIR— output directory (default./psn-export)--format LIST— comma list ofcsv,json,md,all(defaultcsv,json);mdis a markdown report
Display
--top N,--sort enjoyment|hours|recent|title,--quiet,--silent,--verbose,--no-color,--version
Exit codes: 0 ok · 1 fatal · 2 auth · 3 nothing matched.
About your NPSSO token
- An NPSSO is a session cookie. Treat it like a password: anyone with it can act as you on PSN.
- It expires after ~60 days; regenerate it when auth starts failing.
psnstatssends it only to Sony's own API endpoints — never to any third party.- Prefer a file over an env var for long-term use, and lock it down:
chmod 600 ~/.config/psnstats/npsso.psnstatswarns if the file is group/world-readable. - Avoid the inline
--npssoflag except for a quick test: it lands in your shell history and is visible inpsoutput. Use--npsso-fileor$PSN_NPSSOinstead.
FAQ
Can I export PS3 or Vita playtime? No. Sony's API simply does not expose playtime for PS3/Vita titles, so no tool can.
Will this get my account banned? It uses the same unofficial API as other community tools, plus psnawp's built-in rate limiting (300 req / 15 min). Normal, occasional runs are low-risk, but there is no official guarantee. Don't hammer it.
Can I export a friend's library? Only their public titles, via --user THEIR_ONLINE_ID, and only if their privacy settings allow it.
Can I export my wishlist? Yes: --wishlist writes wishlist.csv/wishlist.json with name, edition, platforms, and current price/discount (your own account only; Sony exposes no public wishlist). Fair warning: there is no documented wishlist API, so this rides the same persisted GraphQL query the PS App uses. If Sony rotates it, the flag fails with a clear error until psnstats updates the query.
Roadmap
- Purchased-games list → an "owned but never played" backlog report
- Genre/metadata enrichment (external catalog join)
- A Steam adapter reusing the same pure analysis engine
stdoutstreaming for piping into other tools
Contributing
Issues and PRs welcome. Dev setup:
git clone https://github.com/t3chnaztea/awesome-psnstats
cd awesome-psnstats
pip install -e ".[dev]"
ruff check . && pytest
Disclaimer
psnstats is an unofficial tool. It is not affiliated with, endorsed by, or supported by Sony Interactive Entertainment. "PlayStation", "PS4", and "PS5" are trademarks of Sony Interactive Entertainment Inc. Built on the excellent psnawp library.
License
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file awesome_psnstats-1.1.0.tar.gz.
File metadata
- Download URL: awesome_psnstats-1.1.0.tar.gz
- Upload date:
- Size: 37.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f35e0a5743d1076c7dd3bccb577f59dfb12eb2694a8571773e8cd3078ccc37b
|
|
| MD5 |
2047270cce13f7ab75b8c56f149b9e28
|
|
| BLAKE2b-256 |
130cab6960055543489a8aa736e57fae51df9eaba62fb54ecf0f2f339276e21c
|
Provenance
The following attestation bundles were made for awesome_psnstats-1.1.0.tar.gz:
Publisher:
release.yml on t3chnaztea/awesome-psnstats
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
awesome_psnstats-1.1.0.tar.gz -
Subject digest:
2f35e0a5743d1076c7dd3bccb577f59dfb12eb2694a8571773e8cd3078ccc37b - Sigstore transparency entry: 2158176623
- Sigstore integration time:
-
Permalink:
t3chnaztea/awesome-psnstats@7b5508d3ddeaf7d239b52b22ec69749c7c3d1873 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/t3chnaztea
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7b5508d3ddeaf7d239b52b22ec69749c7c3d1873 -
Trigger Event:
push
-
Statement type:
File details
Details for the file awesome_psnstats-1.1.0-py3-none-any.whl.
File metadata
- Download URL: awesome_psnstats-1.1.0-py3-none-any.whl
- Upload date:
- Size: 27.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df33059f52e92506eac986278932aa587d203c2e55648132f183861bfa2de9c8
|
|
| MD5 |
804f66a5de00fa6c7f03b5f62ed09d60
|
|
| BLAKE2b-256 |
bed8cb2fa0a796ed3e07bd31d08981537a026e72ba55adf7fc94cad6a3cc24f8
|
Provenance
The following attestation bundles were made for awesome_psnstats-1.1.0-py3-none-any.whl:
Publisher:
release.yml on t3chnaztea/awesome-psnstats
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
awesome_psnstats-1.1.0-py3-none-any.whl -
Subject digest:
df33059f52e92506eac986278932aa587d203c2e55648132f183861bfa2de9c8 - Sigstore transparency entry: 2158176694
- Sigstore integration time:
-
Permalink:
t3chnaztea/awesome-psnstats@7b5508d3ddeaf7d239b52b22ec69749c7c3d1873 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/t3chnaztea
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7b5508d3ddeaf7d239b52b22ec69749c7c3d1873 -
Trigger Event:
push
-
Statement type: