Skip to main content

checkleaked-spotify-api

PyPI version Python versions CI license: MIT

Typed Python SDK for the Spotify Data API, covering the same 106 methods and 23 namespaces as @checkleaked/spotify-api. It works with both the RapidAPI spotify81 API and the direct CheckLeaked API.

This is a data API client. It does not require Spotify OAuth credentials.

Links: API reference · Status page · Changelog · Support: admin@checkleaked.cc

Install

pip install checkleaked-spotify-api

Quick start

from spotify_api_sdk import SpotifyApiClient

spotify = SpotifyApiClient(api_key="your-rapidapi-key")

# Play counts for up to 50 tracks per call
counts = spotify.tracks.counts(
    ["0VjIjW4GlUZAMYd2vXMi3b", "spotify:track:7ouMYWpwJ422jRcDASZB7P"]
)

results = spotify.search.search(
    "daft punk",
    type="artists",
    limit=5,
)

# slim=True drops the heavy blocks; stats and top tracks are kept
artist = spotify.artists.overview(
    "spotify:artist:4tZwfgrHOc3mvqYlEYSvVi",
    slim=True,
)

lyrics = spotify.tracks.lyrics(
    "https://open.spotify.com/track/0DiWol3AO6WpXZgp0goxAV",
    format="lrc",
)

status = spotify.status()  # per-endpoint-family service status

Methods return the API's payload. Endpoints that wrap it in {success, data, metadata} are unwrapped to data; use client.request_raw(...) when you need the complete envelope.

Play counts

Need Method
Many tracks (up to 50 per call) tracks.counts(ids)
One track, by id or ISRC partner.track_count(spotify_track_id=...) / (isrc=...)
Track + album + artists + play count partner.track(id, slim=True)
Every track of an album partner.album(id) or albums.tracks(id)
Every track of a playlist partner.playlist(id)

Spotify reports 0 for tracks with fewer than 1,000 plays. tracks.counts needs an API release that serves /partner/tracks/count; an older deployment answers 404, so fall back to partner.track_count() per id.

Providers

RapidAPI is the default and automatically adds x-rapidapi-host: spotify81.p.rapidapi.com:

spotify = SpotifyApiClient(
    api_key="your-rapidapi-key",
    provider="rapidapi",
)

The direct API exposes the same methods and paths. Use a key issued by the direct portal:

spotify = SpotifyApiClient(
    api_key="your-direct-api-key",
    provider="proxy",
)

The API key may be omitted when SPOTIFY_API_KEY or RAPIDAPI_KEY is set.

Pythonic and npm-compatible names

Python methods use snake_case, while npm-style camelCase aliases are also available:

spotify.artists.top_tracks(id, market="US")
spotify.artists.topTracks(id, market="US")  # exact npm-style alias

Every method supports per-call request_timeout, request_retries, request_headers, and an additional extra_query mapping. POST methods also accept a free-form body mapping. The timeout argument of search.search() is different: it is the API's own search budget in milliseconds, and it can only shorten a search, which ends within about 20 seconds anyway.

Responses are cached for a while (play counts about an hour, catalog objects up to a day). Pass extra_query={"cache": "false"} to skip the cached copy; a given URL is refreshed at most once every 10 seconds.

IDs, URIs, and URLs

Spotify IDs may be supplied as bare IDs, Spotify URIs, or open.spotify.com URLs. Multi-ID methods accept comma-separated strings or Python sequences.

from spotify_api_sdk import normalize_id, normalize_ids

normalize_id("spotify:track:0DiWol3AO6WpXZgp0goxAV")
normalize_ids([
    "spotify:artist:4tZwfgrHOc3mvqYlEYSvVi",
    "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02",
])

Spotify relinks some tracks to another id in a market: tracks.get then returns an object whose id differs from the one you asked for, with linked_from.id set to your id.

tracks.get, albums.get and artists.get leave out ids they have no object for and list them in one of two arrays: missing means Spotify does not know the id (asking again will not help); unavailable means it could not be fetched this time, so ask for those ids again later. When none of the ids could be fetched, the call raises a 503 UPSTREAM_UNAVAILABLE error instead (retried automatically). tracks.get_by_id raises 404 for an id Spotify does not know and 503 when it could not be fetched.

result = spotify.tracks.get(ids)
retry_later = result.get("unavailable", [])  # ask again later
not_on_spotify = result.get("missing", [])   # drop for good

Pagination

from spotify_api_sdk import collect

items = collect(
    lambda **page: spotify.artists.albums(id=artist_id, **page),
    get_items=lambda response: (
        response.get("data", {})
        .get("artist", {})
        .get("discography", {})
        .get("albums", {})
        .get("items", [])
    ),
    limit=50,
    max_items=500,
)

Errors

Every failure raises a SpotifyApiError subclass. A 2xx body that reports a failure (success: false, error: true, or an error code such as LYRICS_NOT_AVAILABLE for a track without lyrics) raises too.

from spotify_api_sdk import (
    AuthError,
    HttpError,
    RateLimitError,
    SpotifyApiError,
    TimeoutError,
)

try:
    spotify.search.search("daft punk")
except RateLimitError as error:
    print(error.code, error.retry_after_ms)  # RATE_LIMITED / QUOTA_EXCEEDED
except AuthError:
    print("Invalid or unsubscribed API key")
except SpotifyApiError as error:
    print(error.status, error.code, error.request_id, error.param, error.retryable)
HTTP code Meaning
400 INVALID_PARAMETER, MISSING_PARAMETER Fix the request (error.param)
401 MISSING_API_KEY, INVALID_API_KEY, KEY_REVOKED, KEY_EXPIRED Key problem
404 NOT_FOUND, UNKNOWN_ENDPOINT Entity or route does not exist
422 VIDEO_UNAVAILABLE, AGE_RESTRICTED, PREMIUM_ONLY Downloads only
429 RATE_LIMITED, QUOTA_EXCEEDED Your rate limit or quota
503 UPSTREAM_UNAVAILABLE, UPSTREAM_THROTTLED, LOAD_SHED Temporary, retried automatically
504 UPSTREAM_TIMEOUT Temporary, retried automatically

Spotify-side problems arrive as 503 with Retry-After, never as 401/429. 429 and 5xx responses are retried with backoff, honoring Retry-After (or the body's retry_after_s); errors that waiting cannot fix (QUOTA_EXCEEDED, a bad or revoked key, retryable: false) are raised immediately. No single wait is longer than max_retry_delay (default 10 seconds), even when Retry-After asks for more (error.retry_after_ms still reports what the API asked for), and a 504, which means the API already spent its whole time budget on the request, is retried at most gateway_timeout_retries times (default once). Quote error.request_id when you contact support.

Tracking and webhooks

spotify.tracking.track("artist", "06HL4z0CvFAxyc27GXpf02", label="Taylor")
changes = spotify.tracking.logs(
    spotify_type="artist",
    change_type="monthly_listeners_change",
)

spotify.webhooks.register(
    "37i9dQZF1DXcBWIGoYBM5M",
    "https://example.com/spotify-hook",
    events=["playlist.tracks.added", "playlist.tracks.removed"],
)

Tracked items and webhooks belong to the calling account; RapidAPI identifies you automatically. Tracking also works with a direct API key; webhooks are not available with direct API keys yet.

Configuration

spotify = SpotifyApiClient(
    api_key="...",
    provider="rapidapi",   # rapidapi (default) | proxy
    timeout=30,
    retries=2,
    retry_delay=0.5,
    max_retry_delay=10,          # longest wait before a retry, in seconds
    gateway_timeout_retries=1,   # retries a 504 may use (0 = never)
    headers={"x-my-header": "value"},
    debug=True,
    on_request=lambda info: print("request", info["url"]),
    on_response=lambda info: print("response", info["status"]),
    on_retry=lambda info: print("retry", info["attempt"]),
)

The client is also a context manager:

with SpotifyApiClient(api_key="...") as spotify:
    markets = spotify.markets.get()

See API_REFERENCE.md for every namespace and method.

Metadata

Release files for checkleaked-spotify-api 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for checkleaked-spotify-api 2.0.0
File Size Uploaded
checkleaked_spotify_api-2.0.0.tar.gz 37.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for checkleaked-spotify-api 2.0.0
File Interpreter ABI Platform
checkleaked_spotify_api-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 64.4 kB

Release files / checkleaked_spotify_api-2.0.0.tar.gz

Download URL checkleaked_spotify_api-2.0.0.tar.gz
Size 37.8 kB
Tags Source
SHA-256 checksum
How to use checksums
3e360c9d85c738994b35e98f612ee7368069aef1b3a699b0daed3ef91382c59f
BLAKE2b-256 checksum
How to use checksums
a5457a24271c04ba8f20bf3f8936ba541b3852433d78873187577df2135a089c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.6

Release files / checkleaked_spotify_api-2.0.0-py3-none-any.whl

Download URL checkleaked_spotify_api-2.0.0-py3-none-any.whl
Size 26.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
48ee4e5bb5558520dcf6fafbc9e4d9b970de0bda0932bad9ab66baeb5e6be9c6
BLAKE2b-256 checksum
How to use checksums
5b24d2520fc4f74b76fd7ebc0b6aada1f7277201c63edccd7504e3aed0ba41b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.6

Release history Release notifications | RSS feed

2.0.1

2 release files

This release

2.0.0 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page