Spotify Album Search API. Albums matching your search.
Albums by keyword, artist or UPC. We handle the proxies, blocks and platform changes.
Spotify Album Search API at a glance
Searches Spotify albums, singles and EPs by keyword, artist or UPC, in any language, and returns them a page at a time in Spotify's order. Each has its title, type, credited artists with their IDs, cover and release year. Spotify's filters work in the query: upc: finds a release by its barcode and tag:new the newest. The Spotify Album API adds the full date, label, UPC, copyrights and tracks.
GET /v1/spotify/search_albums
- 1 credit per page, $0.75–$1.97 per 1,000 pages
- 20 typed fields null when unknown
- 100 albums per page, Spotify's own ranking for the query
queryis all it needs, e.g.rick astley
Send one request. Get up to 100 albums back.
Copy the request in your language, or hand it to your agent. Sign up for an API key and your first 100 credits are free.
$ npm install socialtapquery = rick astleyconst params = new URLSearchParams({
query: "rick astley",
});
const res = await fetch(`https://socialtap.dev/v1/spotify/search_albums?${params}`, {
headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, page, meta } = body;
console.log(data, meta.credits_charged);import os
import requests
res = requests.get(
"https://socialtap.dev/v1/spotify/search_albums",
params={"query": "rick astley"},
headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, page, meta = body["data"], body["page"], body["meta"]
print(data, meta["credits_charged"])require "json"
require "net/http"
uri = URI("https://socialtap.dev/v1/spotify/search_albums")
uri.query = URI.encode_www_form('query' => 'rick astley')
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("SOCIALTAP_API_KEY")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
body = JSON.parse(res.body)
raise "#{body["error"]["code"]}: #{body["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
pp body["data"]
puts body["meta"]["credits_charged"]<?php
$query = http_build_query([
'query' => 'rick astley',
]);
$ch = curl_init('https://socialtap.dev/v1/spotify/search_albums?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('SOCIALTAP_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
throw new RuntimeException($body['error']['code'] . ': ' . $body['error']['message']);
}
print_r($body['data']);
echo $body['meta']['credits_charged'], PHP_EOL;package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{}
q.Set("query", "rick astley")
req, err := http.NewRequest("GET", "https://socialtap.dev/v1/spotify/search_albums?"+q.Encode(), nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var body struct {
Data json.RawMessage `json:"data"`
Page json.RawMessage `json:"page"`
Meta map[string]any `json:"meta"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
log.Fatal(err)
}
if body.Error != nil {
log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
}
fmt.Println(string(body.Data), body.Meta["credits_charged"])
}curl -G 'https://socialtap.dev/v1/spotify/search_albums' \
--data-urlencode 'query=rick astley' \
-H "x-api-key: $SOCIALTAP_API_KEY"{
"data": [
{
"approximate_fields": [
"released_at"
],
"artist_name": "Rick Astley",
"artists": [
{
"avatar_url": null,
"display_name": "Rick Astley",
"id": "0gxyHStUsqpMadRV0Di1Qt",
"is_verified": null,
"url": "https://open.spotify.com/artist/0gxyHStUsqpMadRV0Di1Qt",
"username": null
}
],
"copyrights": [],
"cover_url": "https://i.scdn.co/image/ab67616d0000b27315ebbedaacef61af244262a8",
"description": null,
"duration_ms": null,
"genres": [],
"id": "6eUW0wxWtzkFdaEFsTJto6",
"is_explicit": null,
"label": null,
"metrics": {
"track_count": null
},
"platform": "spotify",
"platform_specific": {
"spotify": {
"is_playable": true,
"is_pre_release": false,
"popularity": null,
"pre_release_ends_at": null,
"release_date_precision": "year"
}
},
"released_at": "1987-01-01T00:00:00Z",
"title": "Whenever You Need Somebody",
"tracks": [],
"type": "single",
"unknown_fields": [
"genres",
"copyrights",
"tracks"
],
"upc": null,
"url": "https://open.spotify.com/album/6eUW0wxWtzkFdaEFsTJto6"
},
{
"approximate_fields": [
"released_at"
],
"artist_name": "Rick Astley",
"artists": [
{
"avatar_url": null,
"display_name": "Rick Astley",
"id": "0gxyHStUsqpMadRV0Di1Qt",
"is_verified": null,
"url": "https://open.spotify.com/artist/0gxyHStUsqpMadRV0Di1Qt",
"username": null
}
],
"copyrights": [],
"cover_url": "https://i.scdn.co/image/ab67616d0000b273ad292ed19701d9f5c8cf71b6",
"description": null,
"duration_ms": null,
"genres": [],
"id": "6CWdaSQN5rsdDkOrhFcZ0E",
"is_explicit": null,
"label": null,
"metrics": {
"track_count": null
},
"platform": "spotify",
"platform_specific": {
"spotify": {
"is_playable": true,
"is_pre_release": false,
"popularity": null,
"pre_release_ends_at": null,
"release_date_precision": "year"
}
},
"released_at": "2019-01-01T00:00:00Z",
"title": "The Best of Me",
"tracks": [],
"type": "compilation",
"unknown_fields": [
"genres",
"copyrights",
"tracks"
],
"upc": null,
"url": "https://open.spotify.com/album/6CWdaSQN5rsdDkOrhFcZ0E"
},
{
"approximate_fields": [
"released_at"
],
"artist_name": "Rick Astley",
"artists": [
{
"avatar_url": null,
"display_name": "Rick Astley",
"id": "0gxyHStUsqpMadRV0Di1Qt",
"is_verified": null,
"url": "https://open.spotify.com/artist/0gxyHStUsqpMadRV0Di1Qt",
"username": null
}
],
"copyrights": [],
"cover_url": "https://i.scdn.co/image/ab67616d0000b2733a67639779ccabd632e1a80e",
"description": null,
"duration_ms": null,
"genres": [],
"id": "4C4LvbYS0pxXLW5sGD9EK5",
"is_explicit": null,
"label": null,
"metrics": {
"track_count": null
},
"platform": "spotify",
"platform_specific": {
"spotify": {
"is_playable": true,
"is_pre_release": false,
"popularity": null,
"pre_release_ends_at": null,
"release_date_precision": "year"
}
},
"released_at": "2022-01-01T00:00:00Z",
"title": "Whenever You Need Somebody (Deluxe Edition - 2022 Remaster)",
"tracks": [],
"type": "album",
"unknown_fields": [
"genres",
"copyrights",
"tracks"
],
"upc": null,
"url": "https://open.spotify.com/album/4C4LvbYS0pxXLW5sGD9EK5"
}
],
"page": {
"has_more": true,
"next_cursor": "c1.EXAMPLE_CURSOR",
"next_cursor_expires_at": "2026-10-26T12:00:00Z",
"end_reason": null
},
"meta": {
"request_id": "req_3f9c2a7d1e8b4c6a9f0e2d4b6a8c0e1f",
"platform": "spotify",
"source": "api",
"is_cached": false,
"credits_charged": 1,
"latency_ms": 687,
"fetched_at": "2026-10-25T12:00:00Z",
"input": null,
"credits_remaining": 9999,
"client_request_id": null,
"warnings": []
}
}import { SocialTap } from "socialtap";
const client = new SocialTap(); // apiKey defaults to process.env.SOCIALTAP_API_KEY
const res = await client.spotify.searchAlbums.list({ query: "rick astley" });
console.log(res.data);
console.log(res.credits.charged, res.meta.request_id);import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) throws Exception {
String query = "query=" + encode("rick astley");
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://socialtap.dev/v1/spotify/search_albums?" + query))
.header("x-api-key", System.getenv("SOCIALTAP_API_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
// An error is {"error": {"code", "message", ...}}; success is {data, meta}, meta.credits_charged its price.
if (response.statusCode() >= 400) throw new RuntimeException(response.body());
System.out.println(response.body());
}
static String encode(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8);
}
}using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("x-api-key", Environment.GetEnvironmentVariable("SOCIALTAP_API_KEY"));
var query = string.Join("&",
"query=" + Uri.EscapeDataString("rick astley"));
var res = await http.GetAsync("https://socialtap.dev/v1/spotify/search_albums?" + query);
using var body = JsonDocument.Parse(await res.Content.ReadAsStringAsync());
if (!res.IsSuccessStatusCode)
{
var error = body.RootElement.GetProperty("error");
throw new Exception($"{error.GetProperty("code")}: {error.GetProperty("message")}");
}
Console.WriteLine(body.RootElement.GetProperty("data"));
Console.WriteLine(body.RootElement.GetProperty("meta").GetProperty("credits_charged"));// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }, serde_json = "1"
use std::env;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let res = reqwest::blocking::Client::new()
.get("https://socialtap.dev/v1/spotify/search_albums")
.query(&[("query", "rick astley")])
.header("x-api-key", env::var("SOCIALTAP_API_KEY")?)
.send()?;
let ok = res.status().is_success();
let body: serde_json::Value = res.json()?;
if !ok {
return Err(format!("{}: {}", body["error"]["code"], body["error"]["message"]).into());
}
println!("{} {}", body["data"], body["meta"]["credits_charged"]);
Ok(())
}200 OK · GET https://socialtap.dev/v1/spotify/search_albumsLong arrays and strings are shortened here. Real responses are complete.Docs One schema on 2 platforms.
The response reference lists every field, its type and when it is null. See the full schema.
Null means unknown
A field Spotify doesn't show is null, never zero or an empty string, so a real zero always means zero.
What it accepts
What to search for, as in Spotify's search box: a title, an artist or both, in any language.
Write one parser
Spotify and Apple Music answer in these fields, so the code that reads one reads them all.
platformstring- Platform ID (applemusic, spotify, soundcloud, …).
idstring- Platform-native album ID (string), the one in its page's URL.
urlstring- Canonical album page URL.
typestring- What kind of release it is, as the platform says: album, single, ep or compilation; null when the platform does not say. New values may be added; treat unknown values as album.
titlestring- The release's title as the platform shows it (with an edition or a suffix like "- Single" where it writes one).
descriptionstring- About the release, as plain text (the service's editorial notes, or what its uploader wrote); null when it has none or the platform shows none.
artist_namestring- Who the platform credits for the release, as one display string (it can name more people than have an account linked: artists holds the linked ones); null when the source does not name them.
artistsobject[]- The platform accounts of the artists credited on the release, main artist first, in the platform's order; [] when none is linked, as on a Various Artists compilation (listed in unknown_fields when the source cannot see them).
Live data from 33 platforms.
What teams build with the Spotify Album Search API.
Look up an album ID by its title
Find a release by its UPC
Follow new releases for an artist
Match a release catalog against Spotify
Good to know before you build.
- Results are releases only: the tracks, artists, playlists and podcasts a query matches aren't in the list.
- Search states only the year, so released_at is January 1 of that year, listed in approximate_fields, with platform_specific.spotify.release_date_precision year. The Spotify Album API returns the full date.
- Search lists no tracks, copyrights, label, UPC, length or explicit flag: tracks and copyrights are [] and listed in unknown_fields, the others null, and the Spotify Album API returns them. Spotify files no genres under a release anywhere.
- Results are in Spotify's order, which depends on the page size. A page often holds fewer releases than its limit while next_cursor goes on, and a walk ends with page.end_reason platform_limit where Spotify stops serving, however many it matched.
- The album filters are artist:, album:, year:, upc: and tag:new. track: and genre: return an empty page here (the Spotify Track Search API reads track:). An empty page for a UPC doesn't prove Spotify lacks the release: its search misses some UPCs.
- Spotify answers a weak query with its nearest guesses, so an empty page is rare and any result may be a loose match.
- is_playable says whether Spotify plays the release in the country we request from, which may not be yours.
- When Spotify's search doesn't answer, the first pages come from a web search engine's index, each release read from Spotify, with a partial_data warning naming the fields it lacks, and Spotify's filters are read as plain words. That list holds only what the index has, often a small part of Spotify's, in the engine's order. A next_cursor stays on the list it came from: if Spotify's search stops answering mid-walk, the next page fails with a retryable error instead of switching lists.
- An empty query, a Spotify URI or a link to a Spotify page returns invalid_input, naming the endpoint that takes it where there is one. For a link to Spotify's search page, send its words instead.
1 credit per page. Failed requests are free.
Buy credits once and spend them on any endpoint, on any platform.
| Source | Price per successful page | Per 1,000 pages |
|---|---|---|
| Any source | 1 credit | $0.75–$1.97 |
- Cache hits are free.
- Credits from packs and top-ups never expire.
- A monthly plan's credits are spent first, and what is left of them ends at each renewal.
- Prices exclude tax: sales tax is added at checkout where it applies.
- Outside the US, plans and packs are sold to businesses: checkout asks for your VAT, GST or other business tax ID.
Questions about the Spotify Album Search API.
More in the API reference.
Can I find an album by its UPC?
How much does the Spotify Album Search API cost?
How do I get the next page?
Try it with your own search.
Type it in the playground, or copy the request into your code.
- No credit card
- Failed requests are free
- Works on all 218 endpoints