Reference: Services
Every HTTP call from the frontend goes through a function in src/services/api.ts. For full signatures, parameters, and JSDoc, see the source file on GitHub.
The shared infrastructure
| Symbol | What it does |
|---|---|
apiFetch | The single fetch wrapper used by every service. Handles auth cookies, JSON parsing, error wrapping. |
buildParams | Turns a record of values into URLSearchParams, skipping undefined values. |
ApiError | Thrown by apiFetch on non-2xx responses. Carries the HTTP status and parsed message body. |
Auth and account
| Function | Endpoint | Purpose |
|---|---|---|
fetchUser() | GET /dashboard | Reads the current user from the session cookie. 401 = logged out. |
logoutUser() | POST /api/auth/logout | Ends the server session. |
updateUser() | PATCH /api/user | Updates display name and email. Returns the full updated user. |
deleteAccount() | DELETE /api/user | Permanently deletes the account and all associated data. |
Connected services
| Function | Endpoint | Purpose |
|---|---|---|
fetchConnectedServices() | GET /api/connected-services | Lists every streaming service linked to the account. |
disconnectService() | DELETE /api/connected-services/:provider | Removes one provider link. Caller handles the "last provider" case. |
Listening data
| Function | Endpoint | Purpose |
|---|---|---|
fetchTopTracks() | GET /api/top-tracks | Top tracks for a time range. |
fetchTopArtists() | GET /api/top-artists | Top artists for a time range. |
fetchTopGenres() | GET /api/top-genres | Top genres for a time range. Default limit 5. |
fetchTopSkips() | GET /api/top-skips | Most-skipped tracks. |
fetchTopReplays() | GET /api/top-replays | Most-replayed tracks (back-to-back plays). |
fetchPeakHour() | GET /api/peak-hour | The hour (0–23) with the highest play count. |
fetchMostActiveDay() | GET /api/most-active-day | The single date with the most plays. |
fetchTimeListened() | GET /api/time-listened | Total milliseconds listened in the range. |
fetchHistory() | GET /api/history | Paginated raw plays. |
fetchWrapped() | GET /api/wrapped | Single payload powering the Wrapped slides. |
uploadHistory() | POST /upload | Multipart upload of a Spotify export .zip. |
Conventions
- Every service returns a
Promise<TypedResponse>. timeRangeis optional; omitting it defaults the backend to "all time".- Pagination follows the
Paginationinterface insrc/types/api.ts. - All services throw
ApiErroron non-2xx and are handled at the hook or component layer, not inside services.