Private Spotify analytics dashboard built with Next.js, Vercel, and Upstash Redis. It connects to one personal Spotify account, refreshes listening/library/playlist data server-side, stores snapshots, and renders a modern dark dashboard.
-
Install Node.js 20 or newer.
-
Install dependencies:
npm install
-
Copy the example environment file:
cp .env.example .env.local
-
Create or reuse a Spotify app at https://developer.spotify.com/dashboard.
-
Add these Redirect URIs in Spotify:
http://127.0.0.1:3000/api/spotify/callback https://TU-DOMINIO.vercel.app/api/spotify/callback -
Fill these local variables:
SPOTIFY_CLIENT_ID SPOTIFY_CLIENT_SECRET SPOTIFY_REDIRECT_URI=http://127.0.0.1:3000/api/spotify/callback DASHBOARD_ACCESS_TOKEN CRON_SECRET -
Generate a Spotify refresh token:
npm run spotify:auth
-
Add the printed
SPOTIFY_REFRESH_TOKENto.env.local. -
Run locally:
npm run dev
-
Open http://127.0.0.1:3000, log in with
DASHBOARD_ACCESS_TOKEN, and click Refresh.
Local development can work without Upstash. If Redis is not configured, snapshots are stored at data/spotify-snapshot.json, which is ignored by git.
-
Push this folder to a GitHub repository.
-
In Vercel, import the GitHub repo as a Next.js project.
-
Add Upstash Redis from Vercel Marketplace.
-
Confirm Redis variables exist in Vercel. The app supports either the short names or the longer Marketplace names:
UPSTASH_REDIS_REST_URL UPSTASH_REDIS_REST_TOKENor:
UPSTASH_REDIS_REST_KV_REST_API_URL UPSTASH_REDIS_REST_KV_REST_API_TOKEN -
Confirm these app variables exist in Vercel:
SPOTIFY_CLIENT_ID SPOTIFY_CLIENT_SECRET SPOTIFY_REFRESH_TOKEN SPOTIFY_REDIRECT_URI=https://TU-DOMINIO.vercel.app/api/spotify/callback DASHBOARD_ACCESS_TOKEN CRON_SECRET OPENAI_API_KEY OPENAI_MODEL=gpt-4.1-mini OLLAMA_BASE_URL=http://127.0.0.1:11434 OLLAMA_MODEL=llama3.2:3b -
Deploy from
main.
Pushes to main deploy production. Pull requests create preview deployments.
GET /api/spotify/snapshotreturns the current snapshot and analytics.POST /api/spotify/refreshrefreshes Spotify data and saves a snapshot.GET /api/spotify/statuschecks configuration without exposing secrets.GET /api/spotify/token-healthtests Spotify token refresh without pulling data.GET /api/spotify/callbackexchanges a Spotify auth code for a refresh token./api/cron/refresh-spotifyrefreshes Spotify from Vercel Cron or GitHub Actions when called withCRON_SECRET.
The dashboard avoids Spotify endpoints restricted for newer apps, including Audio Features, Audio Analysis, Recommendations, and Related Artists.
The dashboard includes an AI Listening Brief card. It can summarize patterns, surprises, recommendations, and playlist ideas from the current Spotify snapshot.
- With
OPENAI_API_KEY, the app calls OpenAI server-side. - With
OLLAMA_BASE_URLorOLLAMA_MODEL, the app can call a local Ollama model. - Without either provider, the app uses a deterministic local fallback so the feature still works in demos.
- The brief is saved back into the current snapshot in Upstash Redis or the local
data/spotify-snapshot.jsonfallback.
To use Ollama locally:
brew install ollama
ollama pull llama3.2:3b
ollama serveThen set:
OPENAI_API_KEY=
OLLAMA_BASE_URL=http://127.0.0.1:11434
OLLAMA_MODEL=llama3.2:3bProvider order is OpenAI, then Ollama, then deterministic fallback. Set AI_FALLBACK_ON_ERROR=false if you want provider errors to surface instead of falling back.
vercel.json configures a daily Vercel Cron refresh at 08:00 UTC.
If Vercel Cron is unavailable, use the included GitHub Actions workflow. Add these GitHub repository secrets:
SPOTIFY_REFRESH_URL=https://TU-DOMINIO.vercel.app/api/cron/refresh-spotify
CRON_SECRET
npm run dev
npm run build
npm run start
npm run spotify:auth
npm run spotify:pull
npm test- Never commit
.env,.env.local, refresh tokens, client secrets, or snapshot data. DASHBOARD_ACCESS_TOKENprotects the UI and private APIs.CRON_SECRETprotects scheduled refreshes.- Rotate Spotify client secrets if they were shared outside your machine.