tidal-api
Navigate the Tidal API specification (23,000+ lines OpenAPI spec). Use when implementing Tidal API integrations, adding new endpoints, or understanding API structure.
When & Why to Use This Skill
This Claude skill provides a powerful interface to navigate and implement the Tidal API by efficiently parsing its massive 23,000+ line OpenAPI specification. It helps developers bypass the manual effort of searching through large documentation files, offering instant access to endpoint details, JSON:API-compliant structures, and implementation best practices for music streaming integrations.
Use Cases
- Implementing Tidal music catalog search and metadata retrieval for tracks, albums, and artists in third-party applications.
- Developing user-specific features such as playlist creation, track management, and library synchronization using OAuth2 (PKCE) authentication.
- Debugging API requests by quickly referencing schema definitions, required parameters, and specific resource relationships.
- Optimizing application performance by utilizing batch endpoints and 'include' parameters to reduce API call overhead.
- Mapping complex data structures like ISO 8601 durations and high-resolution artwork assets to local application models.
| 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)