Move all server calls from the deprecated legacy routes to /api/v1, with token authentication. The legacy routes still work but send a Deprecation: true header and will be removed later (see Sansan/MusicServer#31).
Do #1 (start sync with POST) first, or together with this.
Token flow
POST /api/v1/token with JSON {"password": "<API password>", "client_type": "web"} returns {"token", "expires_at", "client_type"}. The token is valid for 24 hours.
Send it on every /api/v1 request: Authorization: Bearer <token>.
A missing, unknown or expired token returns 401 with {"error": "..."}.
Token creation is rate-limited to 10 requests per minute per client (429). Request once and reuse.
If the server has no API_PASSWORD set, any password works. If it has DISABLE_SESSION_AUTH=true, no token is needed.
Suggested structure
One shared axios instance (for example src/api.js) with baseURL: window.__RUNTIME_CONFIG__.API_HOSTNAME + "/api/v1", instead of building URLs in each component.
A request interceptor that adds Authorization: Bearer <token>.
A response interceptor that, on 401, requests a new token once and retries the request once.
Keep the token in memory (or sessionStorage). Ask for the password once, or read it from runtime config if the server is open (API_PASSWORD empty).
<img src> for character images can't send headers: fetch the image with axios as a blob and use URL.createObjectURL, or keep using the legacy /character?name= until the server offers another way.
/api/v1/character?name= (needs the token, see above)
POST /find (search page HTML)
Unchanged, not part of /api/v1
Responses now also contain UUIDs: /music/info and /music/list have SoundtrackUuid and SongUuid. Statistics are available under /api/v1/statistics/... if statisticsModal.vue should show server data later.
The OpenAPI spec is at <server>/openapi (Swagger UI at /swagger/index.html).
Acceptance criteria
No calls to legacy routes remain (except /find)
Token requested once, reused and refreshed automatically on 401
Works with a password-protected server and with an open one
Move all server calls from the deprecated legacy routes to `/api/v1`, with token authentication. The legacy routes still work but send a `Deprecation: true` header and will be removed later (see Sansan/MusicServer#31).
Do #1 (start sync with POST) first, or together with this.
## Token flow
- `POST /api/v1/token` with JSON `{"password": "<API password>", "client_type": "web"}` returns `{"token", "expires_at", "client_type"}`. The token is valid for **24 hours**.
- Send it on every `/api/v1` request: `Authorization: Bearer <token>`.
- A missing, unknown or expired token returns **401** with `{"error": "..."}`.
- Token creation is rate-limited to **10 requests per minute per client** (429). Request once and reuse.
- If the server has no `API_PASSWORD` set, any password works. If it has `DISABLE_SESSION_AUTH=true`, no token is needed.
## Suggested structure
- One shared axios instance (for example `src/api.js`) with `baseURL: window.__RUNTIME_CONFIG__.API_HOSTNAME + "/api/v1"`, instead of building URLs in each component.
- A request interceptor that adds `Authorization: Bearer <token>`.
- A response interceptor that, on 401, requests a new token once and retries the request once.
- Keep the token in memory (or `sessionStorage`). Ask for the password once, or read it from runtime config if the server is open (`API_PASSWORD` empty).
- `<img src>` for character images can't send headers: fetch the image with axios as a blob and use `URL.createObjectURL`, or keep using the legacy `/character?name=` until the server offers another way.
## Endpoint mapping
| Legacy (current) | `/api/v1` |
|---|---|
| `/music/rand`, `/music/rand/low`, `/music/addPlayed`, `/music/addQue`, `/music/info`, `/music/list`, `/music?song=`, `/music/all`, `/music/reset` | Same path under `/api/v1/...`, same responses |
| `POST /sync`, `GET /sync/progress` | `POST /api/v1/sync`, `GET /api/v1/sync/progress` |
| `/characters` | `/api/v1/character/list` |
| `/character?name=` | `/api/v1/character?name=` (needs the token, see above) |
| `POST /find` (search page HTML) | Unchanged, not part of `/api/v1` |
Responses now also contain UUIDs: `/music/info` and `/music/list` have `SoundtrackUuid` and `SongUuid`. Statistics are available under `/api/v1/statistics/...` if `statisticsModal.vue` should show server data later.
The OpenAPI spec is at `<server>/openapi` (Swagger UI at `/swagger/index.html`).
## Acceptance criteria
- No calls to legacy routes remain (except `/find`)
- Token requested once, reused and refreshed automatically on 401
- Works with a password-protected server and with an open one
Update from MusicServer (develop, commit 973ebf2): the API docs are now generated with Huma instead of swag.
Spec: OpenAPI 3.1 at /openapi.json (also /openapi.yaml, and OpenAPI 3.0 at /openapi-3.0.json). Interactive docs at /docs. /openapi redirects to /openapi.json. Only /api/v1 is documented; legacy routes are hidden but still work.
Health:GET /api/v1/health now exists and needs no token (returns {"status": "up"}).
Sync aliases removed:/sync/new, /sync/quick and /sync/new/full are gone. Use POST /sync and POST /sync/full.
Errors: every error body is {"error": "..."}. Invalid or missing parameters (for example ?song=abc, a malformed UUID, limit=0) now return 422 instead of 400.
Lists: empty lists are [], never null. Arrays in the spec are not nullable.
**Update from MusicServer (`develop`, commit 973ebf2):** the API docs are now generated with Huma instead of swag.
- **Spec:** OpenAPI 3.1 at `/openapi.json` (also `/openapi.yaml`, and OpenAPI 3.0 at `/openapi-3.0.json`). Interactive docs at `/docs`. `/openapi` redirects to `/openapi.json`. Only `/api/v1` is documented; legacy routes are hidden but still work.
- **Health:** `GET /api/v1/health` now exists and needs no token (returns `{"status": "up"}`).
- **Sync aliases removed:** `/sync/new`, `/sync/quick` and `/sync/new/full` are gone. Use `POST /sync` and `POST /sync/full`.
- **Errors:** every error body is `{"error": "..."}`. Invalid or missing parameters (for example `?song=abc`, a malformed UUID, `limit=0`) now return **422** instead of 400.
- **Lists:** empty lists are `[]`, never `null`. Arrays in the spec are not nullable.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Move all server calls from the deprecated legacy routes to
/api/v1, with token authentication. The legacy routes still work but send aDeprecation: trueheader and will be removed later (see Sansan/MusicServer#31).Do #1 (start sync with POST) first, or together with this.
Token flow
POST /api/v1/tokenwith JSON{"password": "<API password>", "client_type": "web"}returns{"token", "expires_at", "client_type"}. The token is valid for 24 hours./api/v1request:Authorization: Bearer <token>.{"error": "..."}.API_PASSWORDset, any password works. If it hasDISABLE_SESSION_AUTH=true, no token is needed.Suggested structure
src/api.js) withbaseURL: window.__RUNTIME_CONFIG__.API_HOSTNAME + "/api/v1", instead of building URLs in each component.Authorization: Bearer <token>.sessionStorage). Ask for the password once, or read it from runtime config if the server is open (API_PASSWORDempty).<img src>for character images can't send headers: fetch the image with axios as a blob and useURL.createObjectURL, or keep using the legacy/character?name=until the server offers another way.Endpoint mapping
/api/v1/music/rand,/music/rand/low,/music/addPlayed,/music/addQue,/music/info,/music/list,/music?song=,/music/all,/music/reset/api/v1/..., same responsesPOST /sync,GET /sync/progressPOST /api/v1/sync,GET /api/v1/sync/progress/characters/api/v1/character/list/character?name=/api/v1/character?name=(needs the token, see above)POST /find(search page HTML)/api/v1Responses now also contain UUIDs:
/music/infoand/music/listhaveSoundtrackUuidandSongUuid. Statistics are available under/api/v1/statistics/...ifstatisticsModal.vueshould show server data later.The OpenAPI spec is at
<server>/openapi(Swagger UI at/swagger/index.html).Acceptance criteria
/find)Update from MusicServer (
develop, commit 973ebf2): the API docs are now generated with Huma instead of swag./openapi.json(also/openapi.yaml, and OpenAPI 3.0 at/openapi-3.0.json). Interactive docs at/docs./openapiredirects to/openapi.json. Only/api/v1is documented; legacy routes are hidden but still work.GET /api/v1/healthnow exists and needs no token (returns{"status": "up"})./sync/new,/sync/quickand/sync/new/fullare gone. UsePOST /syncandPOST /sync/full.{"error": "..."}. Invalid or missing parameters (for example?song=abc, a malformed UUID,limit=0) now return 422 instead of 400.[], nevernull. Arrays in the spec are not nullable.