The high-performance core for the Sunoh Music App, delivering a unified music discovery experience by orchestrating data from multiple industry-leading providers.
Sunoh API is a modern, TypeScript-based middleware designed to bridge the gap between various music sources. It provides a homogeneous data structure, allowing client applications to interact with many providers through a single, consistent interface.
- 🌪️ Unified Search & Home: Intelligent result merging and interleaving from Saavn and Gaana.
- ⚡ Multi-Tier Caching: Robust Redis-backed caching system with granular TTL policies.
- 🎼 Provider-Agnostic Interface: One API for Songs, Albums, Playlists, and Artists regardless of the source.
- 🎤 LRC/Synced Lyrics: High-quality sync lyrics integration via specialized providers.
- 🟢 Gaana Integration Plus: Native support for stream decryption, curated occasions, and radio stations.
- 🐋 Docker Ready: Fully containerized environment for seamless deployment and development.
- Runtime: Node.js (v20+)
- Framework: Fastify (High performance, low overhead)
- Language: TypeScript (Type-safe codebase)
- Database/Cache: Redis (High-speed data persistence)
- Containerization: Docker & Docker Compose
- Deployment: Optimized for Vercel Serverless and Standalone Docker.
The API implements a sophisticated merging algorithm that prioritizes data quality and relevancy. When a search is performed:
- It queries multiple providers (Saavn, Gaana) in parallel using
Promise.allSettled. - It deduplicates results based on internal IDs and normalized titles.
- It cleans "dirty" metadata (e.g., placeholder titles like "Untitled" or "None").
- It prioritizes the highest resolution imagery available (
atwformat).
All source data is mapped to a strictly typed internal schema before returning. This means your frontend doesn't need to know if a song came from Saavn or Gaana; it always receives the exact same JSON structure.
Create a .env file in the root directory:
PORT=3600
REDIS_HOST=redis
REDIS_PORT=6379
# PROVIDER TOKENS
LYRICS_TOKEN=your_token
MEDIA_USER_TOKEN=your_tokenThe fastest way to get up and running:
# Start API and Redis containers
npm run docker:up -- --buildThe API will be available at http://localhost:3600.
# Install dependencies
npm install
# Start development server with auto-reload
npm run devDetailed endpoint specifications can be found in api-endpoints.json.
| Path | Method | Description |
|---|---|---|
/music/home |
GET |
Unified home screen with interleaved charts and releases. |
/music/search |
GET |
Merged search results for songs, albums, and playlists. |
/music/song/:id |
GET |
Full song metadata and streaming URLs. |
/music/occasions |
GET |
Browse curated moods and genres (Gaana focused). |
/lyrics/:name |
GET |
Get LRC/Synced lyrics for a specific track. |
We employ a tiered caching strategy to ensure minimal latency:
- Playlists & Albums: 2 Hours (Tailored for discoverability).
- Home & Occasions: 3 Hours (Optimized for performance).
- Fast-Changing Data: No cache (e.g., real-time streams).
# Production build and run
docker compose up -d --buildThe API is pre-configured for Vercel.
npm run deploy:prodThis project is the backbone of the Sunoh ecosystem. While we welcome community contributions, our priority is maintaining stability for the Sunoh Music App.
- Found a bug? Open a GitHub issue.
- Want to add a provider? Please open a discussion first to align on data mapping.
- Support Sunoh: Visit www.sunoh.online.
Built with ❤️ by the Sunoh Team 🎵