Music — entry 022 of 32
Phishin
Phish.in is a free, listener-run archive of legal live Phish recordings, covering shows, tracks, songs, venues, and tours through its v2 REST API. Read endpoints (shows, tracks, search) are fully public and keyless — a plain GET against /api/v2/shows returns real data with no credentials at all — while account-scoped features like playlists and likes require a logged-in user. The project is open source and privately funded, with an MCP endpoint also available for AI-assistant clients.
Phish.in's v2 REST API serves its live-recording archive — shows, tracks, songs, venues — fully keyless for reads. A live GET to `/api/v2/songs?per_page=1` returned a 200 with real catalog data and no credential sent. CORS is Origin-conditional rather than blanket: the same request repeated with an `Origin` header came back with `access-control-allow-origin: *`, while a bare GET with no `Origin` carried no `access-control-*` header at all (just `vary: Origin`).
GreatAPIs Score
Auth quickstart
- No API key or signup required for the v2 read endpoints — this run's own probe against `/api/v2/songs` returned real catalog data with no credentials at all.
- The older v1 namespace is different: a live, keyless GET to `/api/v1/shows.json` returned HTTP 401 with body `{"success":false,"error":"No API key provided"}` — v1 requires a key even though v2 does not. Account-scoped v2 features (likes, playlists) also need a logged-in user session, separate from this keyless read path.
Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.
List songs in the archive
GEThttps://phish.in/api/v2/songs?per_page=1
{"songs":[{"slug":"i-can-t-get-no-satisfaction","title":"(I Can’t Get No) Satisfaction","alias":null,"original":false,"artist":"The Rolling Stones","tracks_count":1,"tracks_with_audio_count":1,"created_at":"2022-02-27T00:41:13-05:00","updated_at":"2022-02-27T00:41:13-05:00"}],"total_pages":981,"current_page":1,"total_entries":981}`total_entries`/`total_pages` reflect the live catalog size at request time and will grow as new songs are cataloged — the shape (slug, title, artist, tracks_count) is what's stable across requests.
Developer reference
https://phish.in/api/v2Gotchas & limits
- The v1 API namespace still exists alongside v2 and behaves completely differently: a live, keyless GET to `/api/v1/shows.json` returned HTTP 401 (`{"success":false,"error":"No API key provided"}`), while the same shape of request against `/api/v2/shows` needs no key at all — integration code should point at `/api/v2`, not `/api/v1`.
- An unknown resource returns a plain HTTP 404 with a minimal JSON body: a live GET to `/api/v2/songs/zzznonexistentslug` (a made-up slug) returned `{"message":"Not found"}`, not an empty list or an error envelope.
- The CORS headers only appear when the request carries an `Origin` — they are not sent unconditionally. A live GET to `/api/v2/songs?per_page=1` with an `Origin: https://example.com` header returned `access-control-allow-origin: *`, `access-control-allow-methods: GET, POST, PATCH, PUT, DELETE, OPTIONS, HEAD`, an empty `access-control-expose-headers`, and `access-control-max-age: 600`; the identical request with no `Origin` header returned no `access-control-*` header at all, only `vary: Origin` (reproduced on three consecutive bare GETs this run). This is fine for browser clients, which always send `Origin` on a cross-origin call, but a `curl`/server-side check for CORS support will see nothing unless it sets the header itself.
- Show-detail responses embed each show's full taper notes and setlist commentary as one long free-text `taper_notes` field. Measured on a live GET to `/api/v2/shows?per_page=25` this run: `taper_notes` ranged from 505 to 2534 characters across the 25 most recent shows (the single-show `?per_page=1` probe returned 1591 characters in a 3692-character response), and the full 25-show page came to 72584 characters — worth trimming client-side rather than assuming a compact response for every resource type.