4
7
Fork
You've already forked tidlers
2
Rust library for the TIDAL Music API
  • Rust 100%
Tomkoid 4ce7108645
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
chore(page): refer to pages as page
2026年06月26日 21:42:22 +02:00
.forgejo/workflows ci: cache rustup toolchains and settings 2026年05月01日 15:51:57 +02:00
.github chore(models)!: organize and use a naming convention for all models ( #9 ) 2026年05月04日 19:34:10 +02:00
assets feat: add generic requests from the JSON api openapi.tidal.com/v2 2026年02月25日 19:45:00 +01:00
examples chore(page): refer to pages as page 2026年06月26日 21:42:22 +02:00
src chore(page): refer to pages as page 2026年06月26日 21:42:22 +02:00
.gitignore chore: ignore .debug*.json files 2026年02月10日 22:59:32 +01:00
.woodpecker.yml ci: stop building in release mode 2025年12月17日 21:13:08 +01:00
Cargo.lock build(deps): update dependencies 2026年06月26日 16:02:09 +02:00
Cargo.toml chore(release): prepare for 0.4.1 2026年05月28日 15:55:07 +02:00
cliff.toml build(deps): update dependencies 2026年06月26日 16:02:09 +02:00
LICENSE.txt chore: prepare for release 0.1.0 2026年01月15日 16:59:31 +01:00
README.md chore(release): prepare for 0.4.0 2026年05月17日 16:51:47 +02:00

Tidlers

A Rust library for interacting with the TIDAL music streaming API.

Features

  • Multiple auth flows:
    • OAuth2 device-code flow (TidalAuth::with_oauth())
    • OAuth2 PKCE flow for HiRes streaming (TidalAuth::with_pkce())
    • Client-credentials flow (TidalAuth::with_api_token(...))
    • Direct access token (TidalAuth::with_access_token(...))
  • Access-token refresh support
  • Session persistence (get_json() / from_json())
  • Audio quality support: Low, High, Lossless, HiRes
  • DASH manifest parsing for HiRes playback
  • API support for tracks, albums, artists, playlists, collection, mixes, search, user, and subscription
  • tracing for auth/session/request flows

Projects using Tidlers

Tidlers is still in WIP state, but here are some projects using it:

  • yadal - Command-line downloader with parallel downloads and all quality support
  • Maré Player - COSMIC TIDAL applet/standalone app

Installation

cargo add tidlers

Or use the latest git version:

[dependencies]
tidlers = { git = "https://codeberg.org/tomkoid/tidlers.git" }

Quick Start (OAuth device-code flow)

usetidlers::{auth::TidalAuth,TidalClient};#[tokio::main]asyncfn main()-> Result<(),Box<dynstd::error::Error>>{letauth=TidalAuth::with_oauth();letmutclient=TidalClient::new(&auth);letoauth=client.get_oauth_link().await?;println!("Visit: {}",oauth.verification_uri_complete);client.wait_for_oauth(&oauth.device_code,oauth.expires_in,oauth.interval,None,).await?;letme=client.refresh_user_info().await?;println!("Logged in as: {}",me.username);Ok(())}

PKCE Quick Start

usetidlers::{auth::TidalAuth,TidalClient};#[tokio::main]asyncfn main()-> Result<(),Box<dynstd::error::Error>>{letauth=TidalAuth::with_pkce();letmutclient=TidalClient::new(&auth);letlogin_url=client.initiate_pkce_login()?;println!("Visit: {}",login_url);// After browser redirect, paste the full redirect URL:
letmutredirect_url=String::new();std::io::stdin().read_line(&mutredirect_url)?;client.finish_pkce_login(redirect_url.trim()).await?;client.refresh_user_info().await?;Ok(())}

Session Persistence

letsession_json=client.get_json();std::fs::write("session.json",session_json)?;letsession_data=std::fs::read_to_string("session.json")?;letmutclient=TidalClient::from_json(&session_data)?;client.refresh_access_token(false).await?;client.refresh_user_info().await?;

API Examples

Get track info + playback info

usetidlers::client::models::playback::AudioQuality;lettrack=client.get_track("66035607").await?;println!("{} - {}",track.artist.name,track.title);client.set_audio_quality(AudioQuality::HiRes);letplayback=client.get_track_postpaywall_playback_info("66035607").await?;ifletSome(urls)=playback.get_stream_urls(){println!("Stream URLs: {urls:?}");}

Album + items

letalbum=client.get_album("251380836").await?;println!("Album: {}",album.title);letitems=client.get_album_items("251380836",Some(50),Some(0)).await?;println!("Album items: {}",items.items.len());

Playlist + paginated items

usetidlers::client::models::playlist::{OrderDirection,PlaylistItemsOrder};letplaylist=client.get_playlist("YOUR_PLAYLIST_UUID").await?;println!("Playlist: {}",playlist.title);letplaylist_items=client.get_playlist_items("YOUR_PLAYLIST_UUID",Some(100),Some(0),PlaylistItemsOrder::Index,OrderDirection::Ascending,).await?;println!("Playlist items: {}",playlist_items.items.len());
usetidlers::client::models::search::config::SearchType;letresults=client.search_direct("daft punk",Some(vec![SearchType::Tracks]),Some(10),Some(0)).await?;println!("Found {} top hits",results.top_hits.items.len());

Subscription + mixes

letsubscription=client.subscription().await?;println!("Subscription type: {:?}",subscription.subscription.subscription_type);letmix=client.get_track_mix("66035607",Some(20),Some(0)).await?;println!("Mix items: {}",mix.items.len());

Examples

testing-client

General CLI for testing endpoints and auth flows.

# Device-code OAuth
cargo run -p testing-client -- user-info
# PKCE auth (optional via CLI flag)
cargo run -p testing-client -- --pkce user-info

pkce-login

Minimal PKCE login example.

cargo run -p pkce-login

login-save

Shows login + session persistence usage.

cargo run -p login-save

hires-streamer

HiRes streaming and DASH manifest usage.

cargo run -p hires-streamer

Tracing

Tidlers emits logs via tracing. Example subscriber:

usetracing_subscriber::{fmt,EnvFilter};fn init_tracing(){let_=fmt().with_env_filter(EnvFilter::try_from_default_env().unwrap_or_else(|_|EnvFilter::new("tidlers=debug")),).try_init();}

Then run with:

RUST_LOG=tidlers=debug cargo run -p testing-client -- user-info

Development

cargo build
cargo check --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace --all-targets

Notes

  • OAuth device-code and PKCE flows require browser/user interaction
  • Many endpoints are country-scoped; after restoring a session, call refresh_user_info() before country-scoped requests
  • Rate limiting is not implemented
  • Some parts of code and documentation are written using AI

License

This project is for educational and personal use. Ensure compliance with TIDAL's Terms of Service.

Disclaimer

This is an unofficial library and is not affiliated with or endorsed by TIDAL. Use at your own risk.