name: tidal-api description: Navigate the Tidal API specification (23,000+ lines OpenAPI spec). Use when implementing Tidal API integrations, adding new endpoints, or understanding API structure.
Tidal API Navigation Skill
Use this skill to navigate the Tidal API specification located at tidal/tidal-api-oas.json (23,000+ lines).
API Overview
The Tidal API is a JSON:API-compliant REST API at https://openapi.tidal.com/v2.
Key Characteristics
- Content-Type:
application/vnd.api+json - Pagination: Cursor-based (
page[cursor]parameter) - Batch limits: Most endpoints support max 20 items per request
- Filtering: Use
filter[field]query params (e.g.,filter[id],filter[isrc]) - Includes: Use
includeparam to embed related resources in response
Resource Types (Tags)
| Resource | Description | Key Endpoints |
|---|---|---|
| albums | Album metadata, tracks, artists | /albums, /albums/{id} |
| artists | Artist info, discography | /artists, /artists/{id} |
| tracks | Track metadata, lyrics, audio | /tracks, /tracks/{id} |
| playlists | User playlists | /playlists, /playlists/{id} |
| searchResults | Search across catalog | /searchResults/{query} |
| searchSuggestions | Autocomplete | /searchSuggestions/{query} |
| userCollections | User's saved library | /userCollections/{id} |
| users | User profiles | /users/me |
| lyrics | Song lyrics | /lyrics, /lyrics/{id} |
| artworks | Image assets | /artworks, /artworks/{id} |
| videos | Music videos | /videos, /videos/{id} |
| genres | Genre metadata | /genres, /genres/{id} |
| providers | Content providers | /providers, /providers/{id} |
Common Endpoints
Search
GET /searchResults/{query}
- countryCode: required (e.g., "US")
- include: albums,artists,playlists,topHits,tracks,videos
- explicitFilter: INCLUDE|EXCLUDE
Tracks
GET /tracks
- filter[id]: comma-separated track IDs (max 20)
- filter[isrc]: comma-separated ISRCs (max 20)
- include: albums,artists,genres,lyrics,providers
GET /tracks/{id}
- include: albums,artists,genres,lyrics
GET /tracks/{id}/relationships/albums
GET /tracks/{id}/relationships/artists
GET /tracks/{id}/relationships/lyrics
Albums
GET /albums
- filter[id]: comma-separated album IDs (max 20)
- filter[barcodeId]: barcode/EAN/UPC
- include: artists,coverArt,genres,items
GET /albums/{id}
- include: artists,coverArt,genres,items
GET /albums/{id}/relationships/items # Track listing
- include: items
Artists
GET /artists
- filter[id]: comma-separated artist IDs
GET /artists/{id}
- include: albums,biography,profileArt,tracks
GET /artists/{id}/relationships/albums
GET /artists/{id}/relationships/tracks
Playlists (requires user auth)
GET /playlists
- filter[id]: playlist UUIDs
- filter[owners.id]: user ID
- include: coverArt,items,ownerProfiles
- sort: createdAt,-createdAt,lastModifiedAt,-lastModifiedAt,name,-name
POST /playlists # Create playlist
- Body: { data: { type: "playlists", attributes: { name, accessType } } }
- accessType: PUBLIC|UNLISTED|PRIVATE
GET /playlists/{id}/relationships/items
POST /playlists/{id}/relationships/items # Add tracks
DELETE /playlists/{id}/relationships/items # Remove tracks
User Library (requires user auth)
GET /users/me # Get authenticated user
GET /userCollections/{userId}/relationships/albums
GET /userCollections/{userId}/relationships/tracks
GET /userCollections/{userId}/relationships/playlists
GET /userCollections/{userId}/relationships/artists
- include: albums|tracks|playlists|artists (matching resource type)
- Returns meta.addedAt for each item
Key Schema Types
Track Attributes
title,version(remix info)isrc(International Standard Recording Code)duration(ISO 8601, e.g., "PT3M45S")explicit(boolean)popularity(0.0-1.0)bpm,key,keyScaletoneTags(mood tags like "Happy")mediaTags(quality: HIRES_LOSSLESS, LOSSLESS)
Album Attributes
title,versionbarcodeId(EAN-13/UPC-A)duration(ISO 8601)numberOfItems,numberOfVolumesreleaseDate(ISO 8601 date)type(ALBUM|EP|SINGLE)explicit,popularity
Artist Attributes
name,handlepopularity(0.0-1.0)contributionsEnabled,contributionsSalesPitch
Playlist Attributes
name,descriptionaccessType(PUBLIC|UNLISTED|PRIVATE)createdAt,lastModifiedAtnumberOfItems,duration
How to Search the Spec
Find endpoint details
# List all paths
jq -r '.paths | keys[]' tidal/tidal-api-oas.json
# Get specific endpoint
jq '.paths["/tracks"]' tidal/tidal-api-oas.json
jq '.paths["/albums/{id}/relationships/items"]' tidal/tidal-api-oas.json
# Search for endpoints containing a term
jq -r '.paths | keys[] | select(contains("playlist"))' tidal/tidal-api-oas.json
Find schema definitions
# List all schemas
jq -r '.components.schemas | keys[]' tidal/tidal-api-oas.json
# Get specific schema
jq '.components.schemas.Tracks_Attributes' tidal/tidal-api-oas.json
jq '.components.schemas.Albums_Attributes' tidal/tidal-api-oas.json
jq '.components.schemas.Playlists_Attributes' tidal/tidal-api-oas.json
# Search for schemas by pattern
jq -r '.components.schemas | keys[] | select(contains("Playlist"))' tidal/tidal-api-oas.json
Find request/response bodies
# Get POST request body schema
jq '.paths["/playlists"].post.requestBody' tidal/tidal-api-oas.json
# Find the referenced schema
jq '.components.schemas.PlaylistCreateOperation_Payload' tidal/tidal-api-oas.json
# Get response schema
jq '.paths["/tracks/{id}"].get.responses["200"]' tidal/tidal-api-oas.json
Find security requirements
# Check auth for an endpoint
jq '.paths["/playlists"].post.security' tidal/tidal-api-oas.json
# List all security schemes
jq '.components.securitySchemes' tidal/tidal-api-oas.json
Authentication
Two methods:
Client Credentials - App-level access (search, catalog browsing)
- Scope: None needed for public catalog
Authorization Code PKCE - User-level access (playlists, library)
- Scopes:
playlists.read,playlists.write,collection.read,r_usr,w_usr
- Scopes:
Existing Implementation Reference
See backend/src/services/tidalService.ts for working implementations of:
- Search with
include=albums,tracks - Batch track fetch by ISRC (
filter[isrc]) - Batch album fetch by ID (
filter[id]) - Album track listing via relationships
- Playlist creation and track addition
- User library sync (albums/tracks)
Key patterns used:
- Rate limiting with exponential backoff
- Chunking requests to 20 items max
- Building lookup maps from
includedresources - Extracting relationships to resolve IDs
Tips
- Always check
includeoptions - Each endpoint lists available includes - Use batch endpoints - Fetch up to 20 items per request with
filter[id] - Parse ISO 8601 durations - Format is
PT{hours}H{minutes}M{seconds}S - Handle cursor pagination - Check
links.nextorlinks.meta.nextCursor - Artwork sizes - Files array contains multiple sizes (80, 160, 320, 640, 1280)