Discogs Scraper - Vinyl Records, Prices & Price Stats avatar

Discogs Scraper - Vinyl Records, Prices & Price Stats

Pricing

from $1.20 / 1,000 records

Go to Apify Store
Discogs Scraper - Vinyl Records, Prices & Price Stats

Discogs Scraper - Vinyl Records, Prices & Price Stats

Scrape the Discogs catalogue by keyword, filter or link: releases, masters, artists and labels with tracklists, credits, matrix numbers, images and videos. Cross-pressing price statistics: lowest, median, highest and average asking price across an album's pressings, plus want/have demand.

Pricing

from $1.20 / 1,000 records

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Categories

Share

Discogs Scraper: Records, Marketplace Prices & Price Statistics

Discogs Scraper turns the Discogs catalogue and marketplace into structured data. Search by keyword or filter, or paste release, master, artist and label links, and get releases, masters, artists and labels with tracklists, credits, images, videos and live marketplace prices. Turn on Price statistics and every release or master also carries the lowest, median, highest and average asking price across the album's own pressings, not just one pressing's price. Export to JSON, CSV or Excel, or pull results straight into your app through the API.

Why This Scraper?

  • Cross-pressing price statistics. The same album can exist as dozens of pressings with prices that differ by an order of magnitude or more. Turn on Price statistics and a record carries the lowest, median, highest and average asking price sampled across the album's pressings, not just one pressing's number.
  • Four record kinds. Release (a specific pressing), master (an album across every pressing), artist and label, all sharing one flat schema.
  • Nine search filters. Artist, label, genre, style, format, country, year, catalog number and barcode. They combine with a keyword, and they also work completely on their own.
  • Full sort control. Order results by relevance, year, title, format, label, catalog number, country, most collected or most wanted, the same sort keys the catalogue itself offers.
  • No account required. Every route this actor reads is the public, anonymous catalogue API. Adding your own free Discogs token is optional and only speeds up large pulls and unlocks per-condition valuation.
  • Every column always present. Fields a run does not fill ship as null rather than being dropped, so repeated runs join cleanly in a warehouse or spreadsheet.
  • Built for monitoring. Incremental mode returns only new and changed records on a recurring schedule, and a blocked run fails loudly instead of quietly returning an empty dataset.

Use Cases

  • Collectors and sellers pricing a pressing: compare an album's own pressings by asking price, total copies for sale and demand, before buying or listing.
  • Price tracking over time: schedule the actor with incremental mode on to watch an album's price statistics or a search result move, and get only what changed.
  • Music data and analytics projects: build a catalogue dataset of releases, artists and labels with tracklists, credits and identifiers for research or cataloguing tools.
  • Marketplace and reselling tools: feed live marketplace numbers (copies for sale, lowest price, demand ratio) into your own pricing or alerting app.
  • Label and artist research: pull an artist's discography or a label's release history and sub-labels in one structured run.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
kind"release" (also "master", "artist", "label")
recordId / entityId"release:1000001" / 1000001
sourceMode / searchQuery"search" / "sample album"
title / name"Sample Album" (release, master); name on artist and label
artistName / artistNames"Sample Artist" / ["Sample Artist"]
year / country"1991" / "UK"
primaryGenre / primaryStyle"Rock" / "Grunge"
primaryFormat / primaryLabel"Vinyl" / "Sample Records"
catalogNumber / barcodes"SR-1234" / ["0000000000000"]
numForSale / lowestPrice / currency42 / 12.5 / "USD" (one pressing)
priceLowest / priceMedian / priceHighest / priceAverage8.0 / 24.99 / 89.0 / 30.15 (across pressings, when Price statistics is on)
priceVersionsSampled / masterVersionsTotal / totalForSaleAcrossVersions5 / 120 / 61
haveCount / wantCount / wantToHaveRatio3400 / 480 / 0.1412
ratingAverage / ratingCount4.1 / 210
priceSuggestionMint ... priceSuggestionPoorper-condition valuation, only with your own Discogs token
tracklist / trackCountfull tracklist / 8 (with Read the full record on)
images / coverImageUrlimage list / cover URL
url / marketplaceUrlcatalogue page / marketplace listing page
detailLoaded / priceStatsLoadedtrue / true
scrapedAt"2026-09-30T12:00:00+00:00"
changeType / changedFields / firstSeenAt / lastSeenAtincremental mode: "UPDATED" / ["lowestPrice"] / timestamps

Artist records also carry realName, profile, nameVariations, aliases, members, groups, externalUrls, contactEmails and contactPhones. Label records also carry profile, contactInfo, parentLabelId, parentLabelName, subLabels, subLabelCount, contactEmails and contactPhones, all taken from the label's or artist's own published profile block.

How to Use

  1. Pick a mode: search (keyword and filter searches across the catalogue) or url (paste release, master, artist or label links or ids).
  2. Search mode: add searchQueries, choose searchType, and narrow with any of the filters (artist, label, genre, style, format, country, year, catalogNumber, barcode). Filters work with no keyword at all. Order results with sortBy and sortOrder.
  3. Set Max records (maxItems) to control run size and cost, then click Start.
  4. Turn on priceStats for the cross-pressing price distribution, and fetchDetails for the full catalogue entry (tracklist, credits, images). Download the dataset as JSON, CSV or Excel, or read it through the API.

Search by keyword, with cross-pressing price statistics:

{
"mode": "search",
"searchQueries": ["nirvana nevermind"],
"searchType": "release",
"priceStats": true,
"maxPriceVersions": 5,
"currency": "USD",
"maxItems": 10
}

Filter-only search, no keyword:

{
"mode": "search",
"searchQueries": [],
"searchType": "release",
"label": "Sub Pop",
"format": "Vinyl",
"country": "Japan",
"sortBy": "want",
"sortOrder": "desc",
"maxItems": 25
}

Paste catalogue links or ids (release, master, artist, label):

{
"mode": "url",
"startUrls": [
"https://www.discogs.com/release/249504",
"m13814",
"a72872"
],
"fetchDetails": true
}

Daily price monitoring for a search, only what changed:

{
"mode": "search",
"searchQueries": ["blue note 1568"],
"priceStats": true,
"incrementalMode": true,
"stateKey": "blue-note-watch",
"maxItems": 0
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/discogs-scraper").call(run_input={
"mode": "search", "searchQueries": ["nirvana nevermind"], "maxItems": 10
})
for record in client.dataset(run["defaultDatasetId"]).iterate_items():
print(record["title"], record.get("lowestPrice"))

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/discogs-scraper').call({
mode: 'search', searchQueries: ['nirvana nevermind'], maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Search mode, URL mode and price statistics

Search mode results already carry title, artist, year, country, format, labels, genres, styles, barcode and the have/want counts, at no extra charge. Turn on fetchDetails to also read each result's full catalogue entry (tracklist, credits, matrix numbers, images, videos, notes, rating); in URL mode the full record is always read, so that toggle changes nothing there. Turn on priceStats to also walk the album's other pressings and publish the price distribution; this is separate from fetchDetails and can be used alone or together with it. Each result for which either optional lookup succeeds carries one Detail enrichment charge on top of the per-record charge; a lookup that fails still ships the base record, uncharged.

Resume and recurring updates

  • Resume (resumeFromRunId) continues one interrupted run: paste its run or dataset id and the actor skips every record already collected there, so you are not charged twice for the same record.
  • Incremental mode (incrementalMode) is for running the same search or url set again and again (for example daily, to watch a price move). Each record is classified NEW, UPDATED (with changedFields), UNCHANGED (suppressed and not billed unless emitUnchanged is on), REAPPEARED or EXPIRED (only with emitExpired, and only after a run whose scan was not stopped early; see the note below). stateKey names or shares the stored state; leave it empty to let the actor derive one from the search, filter and lookup setup.

A note on Emit expired records and Max records. emitExpired is only produced after a run's live scan reaches a natural end (not stopped early by maxItems or maxPages, and not a resumed run; with several keywords, see the next note). When that condition is met, every tracked record from the state that the live scan did not see this run is returned as EXPIRED, and this batch is not itself limited by maxItems: a small maxItems bounds the live scan, not the size of the EXPIRED batch it can trigger. On a large, long-running monitoring campaign where most of the tracked scope has genuinely disappeared, a capped run can therefore return far more rows, and cost more, than maxItems suggests. If you monitor a large scope with emitExpired on, watch the first few scheduled runs' item counts, or keep maxItems at 0 so the run's own size is the only limit in play.

A note on Emit expired records with several search keywords. With more than one keyword, each keyword gets its own share of maxItems. If one keyword uses up its share while the run as a whole stays under maxItems (because a later keyword returned fewer records than its share), the scan is still treated as complete. The records of the first keyword that were not reached this run are then returned as EXPIRED even though they are still listed, and they come back as REAPPEARED on a later run. If you use emitExpired with several keywords, set maxItems to 0, or give each keyword its own run and stateKey.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify, Settings, Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you have not authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where records should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch (catalogue search) or url (paste catalogue links or ids).
searchQueriesarray(none)Search mode. One or more keywords, each searched separately and given an equal share of Max records. Leave empty for a filter-only search.
searchTypestringreleaseSearch mode. release, master, artist, label or all.
artiststring(none)Search mode filter, restricts results to this artist.
labelstring(none)Search mode filter, restricts results to this record label.
genrestring(none)Search mode filter, one Discogs genre.
stylestring(none)Search mode filter, one Discogs style.
formatstring(none)Search mode filter, one physical or digital format.
countrystring(none)Search mode filter, the country of the pressing.
yearstring(none)Search mode filter, a release year or a range such as 1990-1995.
catalogNumberstring(none)Search mode filter, the label catalog number printed on the spine and label.
barcodestring(none)Search mode filter, a barcode or UPC/EAN.
sortBystringrelevanceSearch mode. relevance, year, title, format, label, catno, country, have (most collected) or want (most wanted).
sortOrderstringdescSearch mode. desc or asc, ignored when sortBy is relevance.
startUrlsarraysample linkURL mode. Catalogue links, /release/<id> paths, or r<id> / m<id> / a<id> / l<id> shorthand. A plain number is read as a release id.
urlsarray(none)Alias for startUrls, entries from both fields are read in order and de-duplicated.
maxItemsinteger20Stop after this many records across the whole run. 0 for no limit.
maxPagesinteger(none, no page limit)Search mode. Each page holds up to 100 records.
fetchDetailsbooleanfalseSearch mode: read each result's full catalogue entry. Always on in URL mode, and never charged there.
priceStatsbooleanfalseBuild the price distribution (lowest, median, highest, average) across an album's pressings, for releases and masters.
maxPriceVersionsinteger5Only used when Price statistics is on. How many of an album's pressings to sample (maximum 25).
currencystringUSDOne of 12 currencies for every marketplace price and price statistic.
resumeFromRunIdstring(none)Continue one interrupted run without re-collecting or re-charging for records it already returned.
incrementalModebooleanfalseReturn only new and changed records on a recurring run of the same search or url set.
stateKeystring(none)Name a monitoring campaign, or deliberately share state across differently configured runs.
emitUnchangedbooleanfalseAlso return (and bill) UNCHANGED records.
emitExpiredbooleanfalseAlso return (and bill) EXPIRED records, only after a run whose scan was not stopped early. With several keywords, use maxItems 0 (see the note under How to Use).
mcpConnectorsarray(none)Optional: send a summary of each record to apps you authorized under Integrations.
notionParentPageUrlstring(none)Notion connector only: page under which records are created.
maxNotifyListingsinteger50Cap on records written to each connector per run. Does not affect the dataset.
proxyConfigurationobjectApify ProxyConnection settings. The default works on every plan and needs no configuration.
discogsTokenstring(none)Optional. Your own free Discogs personal access token, see below.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"kind": "release",
"recordId": "release:1000001",
"entityId": 1000001,
"sourceMode": "search",
"searchQuery": "sample album",
"title": "Sample Album",
"artistName": "Sample Artist",
"artistNames": ["Sample Artist"],
"year": "1991",
"country": "UK",
"primaryGenre": "Rock",
"primaryStyle": "Grunge",
"primaryFormat": "Vinyl",
"primaryLabel": "Sample Records",
"labelNames": ["Sample Records"],
"catalogNumber": "SR-1234",
"barcodes": ["0000000000000"],
"genres": ["Rock"],
"styles": ["Grunge"],
"formatDescriptions": ["Vinyl", "LP", "Album"],
"numForSale": 42,
"lowestPrice": 12.5,
"currency": "USD",
"blockedFromSale": false,
"priceLowest": 8.0,
"priceMedian": 24.99,
"priceHighest": 89.0,
"priceAverage": 30.15,
"priceCurrency": "USD",
"priceVersionsSampled": 5,
"priceVersionsPriced": 5,
"masterVersionsTotal": 120,
"totalForSaleAcrossVersions": 61,
"haveCount": 3400,
"wantCount": 480,
"wantToHaveRatio": 0.1412,
"ratingAverage": 4.1,
"ratingCount": 210,
"trackCount": 8,
"url": "https://www.discogs.com/release/1000001",
"marketplaceUrl": "https://www.discogs.com/sell/release/1000001",
"detailLoaded": true,
"priceStatsLoaded": true,
"scrapedAt": "2026-09-30T12:00:00+00:00",
"changeType": "NEW"
}

Plan Requirement

The default proxy setting works out of the box on every plan and needs no configuration. Adding your own free Discogs personal access token is optional: it raises the catalogue's own per-address pacing budget so large pulls finish faster, and it unlocks the per-condition valuation fields that Discogs shows only to a signed-in member. No Discogs account is needed for the rest of the actor's output.

FAQ

How much does it cost?

You pay per record returned, plus one Detail enrichment charge for each record whose optional extras (full record read, or price statistics) succeeded. The Pricing tab shows the current rates. Use Max records to cap the cost of any run.

This actor collects only publicly available catalogue and marketplace data through Discogs' own documented, anonymous API. You are responsible for how you use the output: follow Discogs' terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Contact details in contactEmails and contactPhones come only from a label's or artist's own public profile block, where they published them themselves.

Can I get only new or changed records on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared records, and unchanged ones are not billed unless you turn on Emit unchanged.

What is the difference between a pressing's price and Price statistics?

lowestPrice and numForSale describe ONE pressing, the exact release you searched or pasted. priceLowest, priceMedian, priceHighest and priceAverage describe the DISTRIBUTION across an album's other pressings, sampled with Price statistics on. A single pressing's lowest price can look cheap or expensive purely by chance; the distribution across pressings is the number that tells you whether that price is actually low or high for the album.

Why did my run fail instead of returning an empty dataset?

If Discogs refuses every request the run stops with a clear message, so "no results matched" is never confused with "nothing could be read". Run it again in a few minutes. A search that genuinely matches nothing, or an incremental run whose records were all unchanged, still succeeds with zero new rows.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

๐Ÿ”— Want more e-commerce data?

Pair this actor with these related scrapers from the same team:

๐Ÿ›’ SeatGeek Scraper
Scrape SeatGeek events with ticket price ranges (lowest, highest, average, median)...
๐Ÿ›’ Reverb Music Gear and Sold Price Guide Scraper
Scrape reverb.com music gear: guitars, amps, synths, pedals, drums and pro audio. Search...
๐Ÿงฉ Anghami Scraper
Scrape Anghami's public catalog by keyword or player URL. Rows carry their kind (song...
๐Ÿ‘— KREAM Korea Scraper
Scrape KREAM (kream.co.kr) sneaker and fashion resale data by keyword search, filters...
๐Ÿงฉ TIDAL Scraper
Scrape TIDAL tracks, albums, artists, playlists and public mixes by search phrase or URL...
๐Ÿ‘— GOAT Scraper
Scrape GOAT (goat.com), the sneaker and streetwear resale marketplace. Search or paste...

๐Ÿ‘‰ Browse all abotapi scrapers

๐Ÿ’ฌ Support & custom scrapers

  • ๐Ÿž Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • ๐Ÿ› ๏ธ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
  • โญ Enjoying it? A quick review on the actor page helps other users find it.