Resources
Developer docs
Phonq is fully open source under the MIT license. Build on it, contribute to it, or run your own instance.
Architecture
How Phonq works
A Next.js App Router frontend streams audio from the Jamendo API, while a Neon PostgreSQL database (via Prisma) powers your library.
Get a Jamendo client ID
1. Create a free account at devportal.jamendo.com 2. Register a new application (any name) 3. Copy your client_id into .env: JAMENDO_CLIENT_ID=your_client_id_here
Configure the database
# .env DATABASE_URL="postgresql://user:pass@your-neon-host/neondb?sslmode=require" AUTH_SECRET="$(npx auth secret)" # or any long random string AUTH_GOOGLE_ID="your_google_client_id" AUTH_GOOGLE_SECRET="your_google_client_secret" npx prisma migrate dev npx prisma generate
Optional: YouTube hybrid fill
# .env — enables YouTube genre-gap fill (e.g. Brazilian funk) YOUTUBE_API_KEY=your_google_cloud_api_key # Bulk-seed a genre from an uploads/curated playlist (cheap, 1 unit/page): npm run sync:youtube -- --playlist=<playlistId> --subgenre=brazilian # Searches are cached in Postgres, so the 100/day search budget lasts forever.
Run locally
npm install npm run dev # → http://localhost:3000 # API health check: curl http://localhost:3000/api/health
Deploy to Vercel
1. Push to GitHub and import into Vercel 2. Add the same env vars in Project → Settings → Environment 3. Deploy. That's it — the schema auto-migrates with prisma migrate deploy
API reference
REST endpoints
GET
/api/healthService health check + catalog statusGET
/api/v1/tracks?tags=…&boost=…&limit=…Public catalog API (read-only, rate-limited)GET
/api/v1/search?q=…Public search API (read-only, rate-limited)GET
/api/tracks?search=…&tags=…&boost=…Search and browse the catalog (used by the app)GET
/api/radiosGenre radiosGET
/track/:idPublic shareable track page (OG tags)GET
/embed/:idMinimal iframe-able playerGET
/api/me/favoritesYour favorites (requires session cookie)POST
/api/me/favoritesAdd a favorite — body { trackId }DELETE
/api/me/favorites?trackId=…Remove a favoritePOST
/api/me/historyRecord a listen — body { trackId, progress, completed }GET
/api/me/playlistsList your playlistsPOST
/api/me/playlistsCreate a playlist — body { name, description }GET
/api/me/playlists/:idPlaylist with its tracksPOST
/api/me/playlists/:id/tracksAdd a track — body { trackId }Public API (v1)
Phonq exposes a thin, read-only catalog API. No key required — just a per-IP rate limit of 30 requests/minute. Build phonk-adjacent tools on it.
Browse
curl "https://phonq.vercel.app/api/v1/tracks?tags=phonk&boost=popularity_week&limit=3"
Search
curl "https://phonq.vercel.app/api/v1/search?q=drift&limit=5"
→ 200 { "query": "drift", "tracks": [ …Track[]… ], "count": 5, "provider": "live" }Embed a player
<iframe src="https://phonq.vercel.app/embed/<track-id>" width="384" height="540" style="border:none" />
Every catalog response includes a provider field: live (Jamendo),degraded (Postgres cache) or static (bundled snapshot).
Want to contribute?
The full source is on GitHub. Pick an issue, submit a PR, or open a discussion. We review everything and ship fast.
View the repository