Discography moved to v2
The v1 discography route was removed. The v2 route returns all albums, singles and EPs by default.
By APIStead Labs
Spotify API, metadata for agents: playlists, albums, artists and tracks. Complete discographies are in v2.
Spotify metadata API for AI agents. The playlist, album, artist, artist top-tracks and track endpoints turn a Spotify URL, URI or 22-character id into a stable JSON shape.
A playlist returns up to 100 ordered tracks with optional album enrichment. An album returns its full track list, disc and track numbers, type, release date and copyright lines. An artist returns one image, monthly listeners, followers, bio when Spotify publishes one, and top tracks. The artist top-tracks endpoint returns the same ranked top tracks with a limit parameter and album context on every track. A track returns its title, artists, album context, release date, duration, explicit flag, preview URL, artwork and copyright lines.
Search and complete artist discographies are available in the Spotify v2 listing. Spotify's public metadata does not expose playlist creation dates or per-track added dates, so those fields are not returned. Playback control, downloads and user-library access are not included.
For AI agents
Spotify metadata for agents: resolve playlist, album, artist, artist top-tracks and track links or ids, with search and complete discographies in the v2 listing. Artist responses include audience stats, bio when published and top tracks. No auth or API key.
Scope
The current release covers public playlists, albums, artists, artist top tracks and tracks. Search and complete artist discographies are available in the Spotify v2 listing. Spotify's public metadata does not expose playlist creation dates or per-track added dates, so those fields are omitted. No playback control, downloads or user-library access.
| Method | Route | Price | Health | Description |
|---|---|---|---|---|
| GET | /spotify/album | $0.02 | Verified · 3 ms | Get Spotify album metadata, cover art, artists, release date, copyright lines and the full ordered track list. |
| GET | /spotify/artist | $0.02 | Verified · 3 ms | Get a Spotify artist profile with monthly listeners, followers, bio when published and top tracks with collaborator ids and album context. |
| GET | /spotify/playlist | $0.02 | Verified · 3 ms | Get Spotify playlist cover art, owner, ordered tracks, artists, artwork, duration and optional album enrichment. |
| GET | /spotify/track | $0.02 | Verified · 3 ms | Get Spotify track metadata, artists, album context, release date, copyright lines, duration, preview URL and artwork. |
| GET | /spotify/artist/top-tracks | $0.02 | Verified · 4 ms | Get a Spotify artist's ranked top tracks with album context, artists, duration, preview URL and artwork. |
GET https://apistead.qd.je/api/v1/spotify/album?url=https://open.spotify.com/album/5WulAOx9ilWy1h8UGZ1gkI{
"album": {
"id": "5WulAOx9ilWy1h8UGZ1gkI",
"uri": "spotify:album:5WulAOx9ilWy1h8UGZ1gkI",
"url": "https://open.spotify.com/album/5WulAOx9ilWy1h8UGZ1gkI",
"name": "Deadbeat",
"type": "album",
"artists": [
{
"id": "5INjqkS1o8h1imAzPqGZBb",
"url": "https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb",
"name": "Tame Impala"
}
],
"playable": true,
"copyrights": [
"℗ 2025 Columbia Records, a Division of Sony Music Entertainment, under exclusive license from Tame Impala"
],
"cover_image": "https://i.scdn.co/image/ab67616d0000b273208500450dcd0fd294d7bd3b",
"duration_ms": 3365184,
"track_count": 12,
"release_date": "2025-10-17",
"explicit_count": 4,
"duration_formatted": "56:05"
},
"source": "spotify",
"tracks": [
{
"id": "4whkhyXTrTgHKZzkUvdwoq",
"uri": "spotify:track:4whkhyXTrTgHKZzkUvdwoq",
"url": "https://open.spotify.com/track/4whkhyXTrTgHKZzkUvdwoq",
"album": {
"id": "5WulAOx9ilWy1h8UGZ1gkI",
"url": "https://open.spotify.com/album/5WulAOx9ilWy1h8UGZ1gkI",
"name": "Deadbeat",
"release_date": "2025-10-17"
},
"title": "My Old Ways",
"artists": [
{
"id": "5INjqkS1o8h1imAzPqGZBb",
"url": "https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb",
"name": "Tame Impala"
}
],
"artwork": "https://i.scdn.co/image/ab67616d0000b273208500450dcd0fd294d7bd3b",
"explicit": true,
"playable": true,
"position": 1,
"disc_number": 1,
"duration_ms": 298783,
"preview_url": "https://p.scdn.co/mp3-preview/...",
"track_number": 1,
"duration_formatted": "4:59"
}
],
"preview": false,
"summary": {
"duration_ms": 3365184,
"track_count": 12,
"explicit_count": 4,
"unique_artists": 1,
"returned_tracks": 12,
"duration_formatted": "56:05",
"average_track_duration_ms": 280432
},
"retrieved_at": "2026-11-10T00:00:00Z"
}The client reads the 402 challenge, pays USDC on Base, then retries with the payment header. The 402 is the authoritative price for the call.
import asyncio
import os
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact.register import register_exact_evm_client
account = Account.from_key(os.environ["EVM_PRIVATE_KEY"])
client = x402Client()
register_exact_evm_client(client, EthAccountSigner(account))
async def main():
async with x402HttpxClient(client) as http:
response = await http.get(
"https://apistead.qd.je/api/v1/spotify/playlist",
params={
"url": "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
"limit": 20,
"include_albums": "true",
"album_limit": 10,
},
)
response.raise_for_status()
print(response.json())
asyncio.run(main())import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { wrapFetchWithPayment } from "@x402/fetch";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY);
const client = new x402Client();
// Base mainnet.
client.register("eip155:8453", new ExactEvmScheme(account));
const paidFetch = wrapFetchWithPayment(fetch, client);
const response = await paidFetch(
"https://apistead.qd.je/api/v1/spotify/playlist",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
url: "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
limit: 20,
include_albums: true,
album_limit: 10,
}),
},
);
console.log(await response.json());curl -i "https://apistead.qd.je/api/v1/spotify/playlist?url=https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M&limit=3"import asyncio
import os
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact.register import register_exact_evm_client
account = Account.from_key(os.environ["EVM_PRIVATE_KEY"])
client = x402Client()
register_exact_evm_client(client, EthAccountSigner(account))
async def main():
async with x402HttpxClient(client) as http:
response = await http.get(
"https://apistead.qd.je/api/v1/spotify/album",
params={"url": "https://open.spotify.com/album/5WulAOx9ilWy1h8UGZ1gkI"},
)
response.raise_for_status()
print(response.json())
asyncio.run(main())import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { wrapFetchWithPayment } from "@x402/fetch";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY);
const client = new x402Client();
// Base mainnet.
client.register("eip155:8453", new ExactEvmScheme(account));
const paidFetch = wrapFetchWithPayment(fetch, client);
const response = await paidFetch(
"https://apistead.qd.je/api/v1/spotify/album",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
url: "https://open.spotify.com/album/5WulAOx9ilWy1h8UGZ1gkI",
}),
},
);
console.log(await response.json());curl -i "https://apistead.qd.je/api/v1/spotify/album?url=https://open.spotify.com/album/5WulAOx9ilWy1h8UGZ1gkI"import asyncio
import os
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact.register import register_exact_evm_client
account = Account.from_key(os.environ["EVM_PRIVATE_KEY"])
client = x402Client()
register_exact_evm_client(client, EthAccountSigner(account))
async def main():
async with x402HttpxClient(client) as http:
response = await http.get(
"https://apistead.qd.je/api/v1/spotify/artist",
params={"url": "https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb"},
)
response.raise_for_status()
print(response.json())
asyncio.run(main())import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { wrapFetchWithPayment } from "@x402/fetch";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY);
const client = new x402Client();
// Base mainnet.
client.register("eip155:8453", new ExactEvmScheme(account));
const paidFetch = wrapFetchWithPayment(fetch, client);
const response = await paidFetch(
"https://apistead.qd.je/api/v1/spotify/artist",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
url: "https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb",
}),
},
);
console.log(await response.json());curl -i "https://apistead.qd.je/api/v1/spotify/artist?url=https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb"import asyncio
import os
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact.register import register_exact_evm_client
account = Account.from_key(os.environ["EVM_PRIVATE_KEY"])
client = x402Client()
register_exact_evm_client(client, EthAccountSigner(account))
async def main():
async with x402HttpxClient(client) as http:
response = await http.get(
"https://apistead.qd.je/api/v1/spotify/artist/top-tracks",
params={
"url": "https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb",
"limit": 5,
},
)
response.raise_for_status()
print(response.json())
asyncio.run(main())import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { wrapFetchWithPayment } from "@x402/fetch";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY);
const client = new x402Client();
// Base mainnet.
client.register("eip155:8453", new ExactEvmScheme(account));
const paidFetch = wrapFetchWithPayment(fetch, client);
const response = await paidFetch(
"https://apistead.qd.je/api/v1/spotify/artist/top-tracks",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
url: "https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb",
limit: 5,
}),
},
);
console.log(await response.json());curl -i "https://apistead.qd.je/api/v1/spotify/artist/top-tracks?url=https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb&limit=5"import asyncio
import os
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact.register import register_exact_evm_client
account = Account.from_key(os.environ["EVM_PRIVATE_KEY"])
client = x402Client()
register_exact_evm_client(client, EthAccountSigner(account))
async def main():
async with x402HttpxClient(client) as http:
response = await http.get(
"https://apistead.qd.je/api/v1/spotify/track",
params={"url": "https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT"},
)
response.raise_for_status()
print(response.json())
asyncio.run(main())import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { wrapFetchWithPayment } from "@x402/fetch";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY);
const client = new x402Client();
// Base mainnet.
client.register("eip155:8453", new ExactEvmScheme(account));
const paidFetch = wrapFetchWithPayment(fetch, client);
const response = await paidFetch(
"https://apistead.qd.je/api/v1/spotify/track",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
id: "4cOdK2wGLETKBW3PvgPWqT",
}),
},
);
console.log(await response.json());curl -i "https://apistead.qd.je/api/v1/spotify/track?id=4cOdK2wGLETKBW3PvgPWqT"APIStead paid one named route from its own wallet, received real product back, and published the on-chain USDC receipt. The badge covers that route, not the whole listing.
Phrases an agent can use to find this route.
Playlist, album, artist, artist top-tracks and track metadata are live now. Search and complete artist discographies are available in the Spotify v2 listing. Each route has its own request and response shape.
It returns the album name, type, artists, release date, one cover image, total tracks, duration, explicit count, copyright lines and the full ordered track list with disc and track numbers.
It returns the artist name, one image, monthly listeners, followers, bio when Spotify publishes one and the artist's top five tracks with collaborator ids, profile URLs, album context and one artwork per track.
Yes, when Spotify publishes one. Monthly listeners and followers are included when Spotify publishes them. The bio is the public About text from the artist page.
The artist endpoint returns the artist profile plus the top five tracks. The artist top-tracks endpoint returns the same ranked tracks with a limit parameter from 1 to 5 and album context on every track. Use the top-tracks route when the agent only needs the ranked tracks.
It returns the track title, artists with ids and profile URLs, album id, name, URL and release date, track release date, duration, explicit flag, playable state, preview URL, one artwork image and copyright lines when Spotify publishes them.
They are separate rights. The © line is the copyright notice for the musical work (composition and lyrics). The ℗ line is the phonogram notice for the sound recording (the master). Spotify publishes both when the rights holders supply them. The API returns each line in the order Spotify provides it, does not merge notices and returns an empty array when Spotify publishes none.
No. The agent sends a public playlist, album, artist or track URL, URI or id and pays per call with x402. There is no Spotify login, OAuth flow or API key for the buyer.
No. The API returns metadata only. It does not download audio, control playback, access a user library or bypass Spotify access controls.
A playlist exposes up to 100 tracks, and the limit parameter can return fewer. An album returns its full track list. An artist returns the top five tracks shown on the public artist page. The artist top-tracks endpoint returns up to five tracks and accepts limit=1 to 5.
No. Spotify's public playlist metadata does not expose the playlist creation date, last updated date, or per-track added timestamps. Those fields require an OAuth-based Spotify API, which this API does not use.
It enriches the first playlist tracks with album id, name, URL and release date, and upgrades each track artwork to the largest available album image. Album enrichment uses extra metadata lookups and is capped by album_limit to keep latency predictable.
Use GET /api/v1/spotify/playlist, /album, /artist, /artist/top-tracks or /track with a url or id query parameter. All five routes also accept POST JSON with a url or id field. The value can be a Spotify URL, URI or 22-character id.
A playlist, album, artist, artist top-tracks or track call costs $0.02 USDC on Base. The agent reads the x402 402 challenge, pays the provider wallet directly and retries. There is no API key or subscription.
The v1 discography route was removed. The v2 route returns all albums, singles and EPs by default.
By APIStead Labs
Added /spotify/artist/discography with Albums, Singles and EPs, Popular releases and Appears On sections from the public artist page, plus release year, type and cover art. This route was later removed in 1.7.0; use the v2 discography route for complete discographies.
By APIStead Labs
Artist and artist top-tracks responses now include monthly listeners, followers, bio when Spotify publishes it and top tracks.
By APIStead Labs
Added /spotify/artist/top-tracks with limit 1-5, ranked top tracks, album context on every track and a summary. The artist endpoint top tracks now include album context too.
By APIStead Labs
The track endpoint now returns the album id, name, URL and release date plus copyright lines when Spotify publishes them. Listing JSON and Markdown now share normalized route fields, payment terms, verification receipts and example responses across all nine listings.
By APIStead Labs
Added the track endpoint with title, artists, release date, duration, explicit flag, playable state, preview URL and one artwork image. Playlist, album and artist now also accept ?id= and an id field in JSON bodies.
By APIStead Labs