Spotify pi Parameter




Spotify Share Links and the pi Parameter: A Privacy Research Analysis



Every Spotify share link contains two query parameters: si and pi. The si is documented — Spotify uses it to build social graphs. The pi is not. In recent months, a claim has been circulating on Telegram and Discord — amplified by AI-generated OSINT guides spreading across Italian, Dutch, German, and UK communities — that pi stands for Profile Identifier and directly exposes the Spotify account of whoever shared the link.

I tested that claim empirically.

Static Analysis of the pi Value



The string g-k1ZIqMToS-- decomposes into a g- prefix and an 11-character body in base64url alphabet, decoding to 8 raw bytes (64 bits).

Identifier Length Decoded size Consistent with
si 22 char 16 bytes (128-bit) Random session token / GUID
pi body 11 char 8 bytes (64-bit) Short opaque token
Canonical Spotify user ID 28 char base62 lowercase Documented user URI format

64 bits is too small for a globally unique identifier on a platform with hundreds of millions of accounts. The structure also does not match canonical Spotify user IDs, which are 22–28 characters of lowercase base62. The g- prefix is claimed by informal sources to indicate Google OAuth registration — there is no evidence for this.

Testing Resolvability: Five Surfaces, One Control


Each test used a control: the canonical user ID 31squddjtl7ycsxqzqfjnx------, confirmed valid via the music:creator meta tag of the share page. If the control passes and pi fails, the conclusion is clear.



Web resolver

GET /user/g-k1ZIqMToS-- returns 404. Control returns 200. pi fails.




Rendered share page

The pi persists in og:url and deeplinks, but the only user URI exposed is the playlist owner, not any account linked to pi. pi fails.




Spotify Web API (Client Credentials & Authorization Code)

Both flows returned 403 for both target and control. Since November 2024, Spotify restricted API access for development-mode apps uniformly — not selectively on pi. Non-discriminating by design.




Desktop deeplink

spotify:user:g-k1ZIqMToS-- returns “Couldn’t find that”. Control opens the correct profile. pi fails.

Surface pi Control Discriminating?
Web resolver /user/{id} 404 200 Yes — pi fails
Share page metadata no user ref Yes — pi fails
Web API (both flows) 403 403 No — endpoint closed
Desktop deeplink not found profile opens Yes — pi fails

What pi Is (Most Likely)


Based on structural and behavioral analysis — not source code access — the most consistent hypothesis is that pi is an opaque playback or share context token: a short-lived identifier Spotify uses internally to attribute plays or share events to a specific context. This explains why it persists in deeplinks while si is dropped from og:url: Spotify preserves playback attribution when the link is opened via the app, without exposing any user identity.

The Real Privacy Issue: the si Parameter


The si parameter is the actual concern. Since the Spotify Messages rollout in late 2025, Spotify uses si to retroactively populate “suggested friends” from years of share history. Sharing a playlist on Telegram or Discord two years ago is enough for Spotify to surface that connection today.

Mitigations: the Firefox extension “Remove Spotify Tracker Parameters”, Brave Browser’s built-in clean link copy, or simply deleting everything after ? before sharing.

Python Sanitizer: Strip Spotify Tracking Parameters


#!/usr/bin/env python3
"""
spotify_link_sanitize.py -- strips si, pi, and all query params from Spotify share links.
Usage: python spotify_link_sanitize.py "https://open.spotify.com/playlist/...?si=...&pi=..."
"""
import sys
from urllib.parse import urlparse, urlunparse

SPOTIFY_HOSTS = {"open.spotify.com", "spotify.link"}

def sanitize(url):
p = urlparse(url.strip())
if p.netloc.lower() not in SPOTIFY_HOSTS:
raise ValueError(f"Not a Spotify URL: {p.netloc}")
removed = dict(kv.partition("=")[::2] for kv in p.query.split("&")) if p.query else {}
clean = urlunparse((p.scheme, p.netloc, p.path.rstrip("/"), "", "", ""))
return clean, removed

if __name__ == "__main__":
clean, removed = sanitize(sys.argv[1])
print(clean)
if removed:
print("Removed:", ", ".join(
f"{k}={v[:20]}..." if len(v) > 20 else f"{k}={v}"
for k, v in removed.items()
), file=sys.stderr)

Conclusion



The claim that pi in Spotify share links exposes the sender’s account is not supported by empirical evidence. Three independent public surfaces that resolve canonical Spotify user IDs do not resolve pi. The parameter is real, undocumented, and persistent — but it is not a user identifier on any publicly reachable surface.

If you found this technique in an AI-generated OSINT guide or a Telegram channel, it does not hold up under testing.

Action item: Strip your Spotify share links before sending them. Delete everything after ? — the link works identically.