Anchor Connector
This is a simple library for connecting to the unofficial Spotify for Creators (formerly Anchor) API. It can be used to export analytics data from your podcast dashboard at https://podcasters.spotify.com.
API Notes
The API is undocumented, unofficial, and subject to change at any time. This library reverse-engineers the requests made by the Spotify for Creators web dashboard.
Base URL
As of early 2026, the active base URL is:
https://podcasters.spotify.com/pod/api/proxy/v3
Previous base URLs that are now defunct:
| URL | Status |
|---|---|
https://api-v5.anchor.fm/v3 |
❌ Dead (returns 401 for all requests) |
https://creators.spotify.com/pod/api/proxy/v3 |
✅ Still works as an alias |
Station and Episode IDs
The API previously used string-prefixed identifiers in URL path segments:
webStationId:<hex-id>for station-level endpointswebEpisodeId:<alphanumeric-id>for episode-level endpoints
These are now replaced by plain numeric IDs throughout all analytics
endpoints. The webStationId you have from your credentials is still useful
as a bootstrap — the episodePage endpoint still accepts it and returns the
numeric stationId in its response. This library handles the conversion
automatically: you only need to supply your webStationId and the numeric ID
is resolved and cached on the first API call.
Episode responses now also include spotifyEpisodeUri (e.g.
spotify:episode:4pvCXSIxpZLPaLlJ4KWiBa) and spotifyShowUri fields, but
the analytics endpoints use the plain numeric episodeId.
GraphQL
The library previously used a GraphQL endpoint
(https://creators-graph.spotify.com/v2/graph-pq) to fetch the full episode
list. This endpoint is no longer available (returns 401). The same data is
now fetched via the REST episodePage endpoint, which is paginated and returns
all fields needed (including episodeId, spotifyEpisodeUri, title, etc.).
The base_graphql_url parameter and ANCHOR_BASE_GRAPHQL_URL environment
variable have been removed from the connector accordingly.
Supported Endpoints
Station-level
podcast_episode— full episode list (wrapsepisodes)episodes— paginated episode iteratortotal_playstotal_plays_by_episodeunique_listenersaudience_sizeplaysplays_by_age_rangeplays_by_appplays_by_deviceplays_by_episodeplays_by_genderplays_by_geoplays_by_geo_cityimpressions
Episode-level
All episode-level endpoints take a numeric episodeId (available as
episode["episodeId"] from episodes()).
episode_playsepisode_performanceepisode_aggregated_performanceepisode_metadata(overview endpoint)
See __main__.py for a full working example of every endpoint.
Credentials
Before you can use the library, you must extract your Anchor/Spotify for Creators credentials from the dashboard; they are not exposed through your account settings.
You can use our web-extension to capture them automatically, or take a look at the code to see how to do it manually.
| Credential | Where to find it |
|---|---|
ANCHOR_BASE_URL |
Use https://podcasters.spotify.com/pod/api/proxy/v3 |
ANCHOR_WEBSTATION_ID |
The short hex ID in your podcast URL, e.g. fb37d7a4 |
ANCHOR_PW_S |
Value of the anchorpw_s cookie on podcasters.spotify.com |
The anchorpw_s cookie expires periodically — if you start getting 401
errors, you need to grab a fresh value from your browser's DevTools
(Application → Cookies → podcasters.spotify.com).
Installation
pip install anchorconnector
Usage
from anchorconnector import AnchorConnector
from datetime import datetime, timedelta
connector = AnchorConnector(
base_url="https://podcasters.spotify.com/pod/api/proxy/v3",
webstation_id=WEBSTATION_ID,
anchorpw_s=ANCHOR_PW_S,
)
end = datetime.now()
start = end - timedelta(days=30)
# Station-level analytics
total_plays = connector.total_plays()
plays_by_geo = connector.plays_by_geo()
plays = connector.plays(start, end)
plays_by_age_range = connector.plays_by_age_range(start, end)
plays_by_app = connector.plays_by_app(start, end)
plays_by_device = connector.plays_by_device(start, end)
plays_by_episode = connector.plays_by_episode(start, end)
plays_by_gender = connector.plays_by_gender(start, end)
# Iterate over all episodes and fetch per-episode analytics
for episode in connector.episodes():
episode_id = episode["episodeId"] # numeric ID, required by analytics endpoints
print(episode["title"])
print(episode["spotifyEpisodeUri"]) # e.g. "spotify:episode:4pvCX..."
plays = connector.episode_plays(episode_id, start, end)
performance = connector.episode_performance(episode_id)
aggregated = connector.episode_aggregated_performance(episode_id)
metadata = connector.episode_metadata(episode_id)
Development
We use Pipenv for virtualenv and dev dependency management. With Pipenv installed:
- Install your locally checked out code in development mode, including its dependencies, and all dev dependencies into a virtual environment:
pipenv sync --dev
- Create an environment file and fill in the required values:
cp .env.sample .env
- Run the script in the virtual environment, which will automatically load
your
.env:
pipenv run anchorconnector
To add a new dependency for use during the development of this library:
pipenv install --dev $package
To add a new dependency necessary for the correct operation of this library, add
the package to the install_requires section of ./setup.py, then:
pipenv install
To publish the package:
make publish
Metadata
Release files for anchorconnector 0.6.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| anchorconnector-0.6.3.tar.gz | 13.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| anchorconnector-0.6.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 26.2 kB
Release files / anchorconnector-0.6.3.tar.gz
| Download URL | anchorconnector-0.6.3.tar.gz |
|---|---|
| Size | 13.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0744a5c433ddf8b826ebe06d84dab567a9749ac5e5d611c2ef7db302097a8cd0
|
|
BLAKE2b-256 checksum How to use checksums |
a21fde4943eb9ab17fedc44a4fc59e7275b2faa9aa8d964c782b7d169043a22a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / anchorconnector-0.6.3-py3-none-any.whl
| Download URL | anchorconnector-0.6.3-py3-none-any.whl |
|---|---|
| Size | 12.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3bfab9c966f117148fceeba92b0d2798ef41eec315d57c5d85da708880f299a6
|
|
BLAKE2b-256 checksum How to use checksums |
815986cc41ff64d1b1b283607f243466c05c899d9cf679c0558d2f80989e8c23
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Security for anchorconnector 0.6.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.