kv-music/tidal-proxy
Admin 431af4bb09
Some checks failed
Lighthouse / lighthouse (push) Failing after 2s
Lint Codebase / lint (push) Failing after 4s
Run Tests / test (push) Failing after 3s
fix: route stream segments through Go proxy in dev mode, reject Tidal PREVIEW (30s demo)
2026-05-18 15:31:47 +07:00
..
.env.example Add self-hosted Tidal proxy server and integrate token forwarding 2026-05-18 12:28:03 +07:00
.gitignore Add self-hosted Tidal proxy server and integrate token forwarding 2026-05-18 12:28:03 +07:00
docker-compose.yml Add self-hosted Tidal proxy server and integrate token forwarding 2026-05-18 12:28:03 +07:00
Dockerfile Add self-hosted Tidal proxy server and integrate token forwarding 2026-05-18 12:28:03 +07:00
go.mod Add self-hosted Tidal proxy server and integrate token forwarding 2026-05-18 12:28:03 +07:00
main.go fix: route stream segments through Go proxy in dev mode, reject Tidal PREVIEW (30s demo) 2026-05-18 15:31:47 +07:00
README.md Add self-hosted Tidal proxy server and integrate token forwarding 2026-05-18 12:28:03 +07:00
tidal-proxy.exe~ fix: route stream segments through Go proxy in dev mode, reject Tidal PREVIEW (30s demo) 2026-05-18 15:31:47 +07:00

Tidal Proxy Server

Self-hosted proxy for Tidal API that provides lossless audio manifests. Compatible with Monochrome and SpotiFLAC-Mobile clients.

Features

  • Proxy Tidal playback info requests (/v1/dl/tid2)
  • UA validation (compatible with SpotiFLAC-Mobile format)
  • Quality enforcement (rejects LOW/HIGH responses when lossless requested)
  • Format extraction from DASH manifests
  • Health check endpoint

Requirements

  • Go 1.21+ (for building from source)
  • Docker (optional, for containerized deployment)
  • A valid Tidal access token (from user login)

Quick Start

Run with Go

cd tidal-proxy
go build -o tidal-proxy
./tidal-proxy

Run with Docker

docker compose up -d

Run with Docker (custom config)

docker run -d \
  -p 8080:8080 \
  -e REQUIRED_UA_PREFIX="SpotiFLAC-Mobile/" \
  -e ALLOW_ANY_QUALITY=false \
  -e COUNTRY_CODE=US \
  tidal-proxy

Configuration

Environment Variable Default Description
PORT :8080 Server listen address
REQUIRED_UA_PREFIX SpotiFLAC-Mobile/ Required User-Agent prefix
ALLOW_ANY_QUALITY false If true, don't reject LOW/HIGH responses
COUNTRY_CODE US Tidal country code for requests

API Endpoints

POST /v1/dl/tid2

Get track playback info and manifest.

Headers:

  • User-Agent: Must start with REQUIRED_UA_PREFIX (e.g., SpotiFLAC-Mobile/4.5.5)
  • Authorization: Bearer <your-tidal-token> (or use X-Tidal-Token header)

Body:

{
  "id": "356965156",
  "quality": "LOSSLESS"
}

Quality values: LOW, HIGH, LOSSLESS, HI_RES_LOSSLESS

Response:

{
  "success": true,
  "data": "{\"trackId\":356965156,\"audioQuality\":\"LOSSLESS\",\"manifest\":\"...\",\"formats\":[\"FLAC\"]}"
}

GET /health

Health check endpoint.

Response:

{
  "status": "ok",
  "uptime": "2h30m15s"
}

GET /auth

Returns auth instructions.

Getting a Tidal Token

This proxy requires a valid Tidal access token. You can obtain one by:

  1. Using the Tidal web app: Open browser dev tools while logged into Tidal, find the Authorization header from any API request
  2. Using OAuth: Register a Tidal developer app at https://developer.tidal.com and use the PKCE flow
  3. From Monochrome: The token is stored in your browser's localStorage after login

Important: Tokens expire. The proxy does not handle token refresh - you need to provide a valid token with each request.

Integration with Monochrome

Update your Monochrome settings to use the self-hosted proxy:

  1. Go to Settings > Tidal Web
  2. Set Proxy URL to http://localhost:8080
  3. The proxy will use your existing Tidal token from Monochrome's localStorage

Or programmatically:

tidalWebSettings.setProxyUrl('http://localhost:8080');

Security Notes

  • Never expose this proxy publicly without proper authentication
  • The proxy forwards your Tidal token to Tidal's API
  • UA validation provides minimal protection - consider adding API keys for production use
  • Tokens are not logged or stored by the proxy