eBay
eBay Sold Listings API: Get Sold Prices and Completed Sales Data
Pull eBay sold prices and completed listings data from 17 marketplaces as JSON or CSV. Input examples, price stats, API code and pricing comps for resellers.
eBay
Pull eBay sold prices and completed listings data from 17 marketplaces as JSON or CSV. Input examples, price stats, API code and pricing comps for resellers.
Asking prices tell you what sellers hope for. Sold prices tell you what the market pays. If you resell, buy stock, value collectibles or build pricing tools, eBay’s completed listings are the comp data you want, and the eBay Sold Listings API turns any keyword into rows of real sales: what sold, for how much, on which day, as an auction or Buy It Now, and from which seller.
It runs on Apify, so you can use it from the browser or call it as an API. No eBay account, developer key or proxy setup is needed.
Each dataset row is one completed sale.
| Group | Fields |
|---|---|
| Sale | soldPrice, currency, soldAt, soldDateText, listingType, bidCount, bestOfferAccepted, hasBestOffer, quantitySold |
| Fees | displayedPrice, buyerProtectionFee, sellerType |
| Shipping | shippingPrice, shippingIsEstimate, shippingText, totalPrice |
| Listing | listingId, title, url, imageUrl, condition, categoryId, categoryName, itemLocation, isPromoted, freeReturns, returnsAccepted |
| Seller | seller.username, seller.feedbackScore, seller.feedbackPercent, seller.isStore |
| Search | searchQuery, site |
Three details make this data usable for pricing rather than just “roughly right”:
soldPrice is what the item sold for. The original figure stays in displayedPrice and the fee in buyerProtectionFee.bestOfferAccepted: true and are left out of the price statistics. Keep that flag in mind whenever you average prices yourself.site). There are 17: US, UK, Germany, France, Italy, Spain, Canada, Australia, Netherlands, Austria, Switzerland, Ireland, Poland, Hong Kong, Malaysia, Philippines and Singapore. Prices always come back in that site’s currency.includeSummary) if you want the median and quartiles.The minimum input is just a keyword:
{
"keywords": ["nintendo switch oled"],
"site": "ebay.co.uk",
"maxItems": 20
}
A raw keyword search mixes in bundles, parts-only units and graded copies, which drag your median around. These inputs fix that:
| Input | What it does |
|---|---|
days |
Sales from the last N days (default 30). eBay keeps roughly the last 90 days. |
soldFrom / soldTo |
A fixed date range, e.g. "2026-09-01" to "2026-09-30". |
excludeKeywords |
Words to leave out, sent to eBay as minus terms and also checked against titles. |
condition |
all, new, used, refurbished or for_parts. |
listingType |
all, auction or buy_it_now. |
sellerType |
all, private or business (supported on eBay’s European sites). |
categoryId |
Restrict the search to one eBay category. |
minPrice / maxPrice |
Sold price range in the marketplace currency. |
includeSummary |
Save per-keyword price statistics to PRICE_STATS. |
categoryId is the number after _sacat= in an eBay search URL. Rather than digging through eBay menus, look it up in our free eBay category ID lookup. IDs can differ between marketplaces, so look up the one for the site you search. Searching in the right category is the single best way to keep accessories and lots out of your comps.
{
"keywords": ["charizard base set 4/102"],
"site": "ebay.com",
"categoryId": "183454",
"days": 30,
"excludeKeywords": ["psa", "bgs", "cgc", "graded", "proxy"],
"maxItems": 200,
"includeSummary": true
}
183454 is CCG Individual Cards on ebay.com, which keeps out sealed product and binders. The exclude list removes graded slabs so the median reflects raw cards.
{
"keywords": ["nintendo switch oled"],
"site": "ebay.co.uk",
"listingType": "auction",
"condition": "used",
"days": 14,
"maxItems": 100
}
{
"keywords": ["lego 75192"],
"site": "ebay.de",
"soldFrom": "2026-09-01",
"soldTo": "2026-09-30",
"maxItems": 300
}
A real row from a UK search. eBay showed £128.62; the item sold for £123.00 and the £5.62 difference was the Buyer Protection fee:
{
"searchQuery": "nintendo switch oled",
"site": "ebay.co.uk",
"listingId": "237102372592",
"title": "Nintendo Switch OLED Model HEG-001 Handheld Console - 64GB - White",
"url": "https://www.ebay.co.uk/itm/237102372592",
"soldPrice": 123,
"currency": "GBP",
"displayedPrice": 128.62,
"buyerProtectionFee": 5.62,
"listingType": "buy_it_now",
"bestOfferAccepted": false,
"condition": "Pre-owned",
"categoryName": "Video Game Consoles",
"soldAt": "2026-10-03T00:00:00.000Z",
"soldDateText": "Sold 3 Oct 2026",
"seller": {
"username": "lpeming",
"feedbackScore": 237,
"feedbackPercent": 100,
"isStore": false
},
"sellerType": "private"
}
With includeSummary: true, the key-value store gets a PRICE_STATS record per keyword: count, countInPriceStats, min, p25, median, mean, p75, max and currency. Every run also writes a SUMMARY record with eBay’s total sold count (advertisedTotal), how many rows were saved, how many were filtered and why, and stoppedBecause. That makes it easy to see whether you hit your maxItems cap or ran out of sales.
cURL, returning the rows directly:
curl -X POST "https://api.apify.com/v2/acts/epicscrapers~ebay-sold-listings-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"keywords": ["vintage seiko"], "site": "ebay.com", "days": 14, "maxItems": 50}'
JavaScript, reading both the rows and the price stats:
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('epicscrapers/ebay-sold-listings-api').call({
keywords: ['airpods pro 2', 'sony wh-1000xm5'],
site: 'ebay.com',
condition: 'used',
days: 30,
maxItems: 100,
includeSummary: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const stats = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('PRICE_STATS');
console.log(items.length, 'sold listings');
console.log(stats.value);
Keep maxItems around 20 to 50 when a person or an AI agent is waiting on the answer; small runs finish in seconds.
Resellers pricing inventory. Before you list, pull 30 days of sold comps for the exact model and condition. List near the median to sell within a week, or near p75 if you can wait.
Buying stock and flipping. Check sell-through before you buy. eBay’s advertisedTotal in SUMMARY shows how many units sold recently, so you can compare demand across products. Pair it with live asking prices from the eBay scraper to spot items listed well below recent sold prices.
Dealers and collectibles. Value cards, watches, LEGO and sneakers on real transactions. Split by listingType to see whether auctions or Buy It Now get better prices in your niche, and use bidCount as a heat signal.
Pricing apps and repricers. Call the actor from your backend with a keyword and read PRICE_STATS as JSON. It’s an alternative to Terapeak (Seller Hub only, no API) and paid price guides.
Market research. Run the same keyword on several marketplaces to compare countries, or schedule a weekly run and keep each dataset. eBay only shows about 90 days of sales, so scheduled runs are how you build a longer price history. Deduplicate overlapping runs on listingId and group by week of soldAt.
You pay per sold listing saved, from $2 to $3.50 per 1,000 depending on your Apify plan. Blocked runs, filtered rows, SUMMARY and PRICE_STATS aren’t charged. The Pricing tab on the actor page always has the current rates.
eBay’s Marketplace Insights API, which covers sold items, is restricted to approved partners. Terapeak shows sold data inside Seller Hub but has no API. This actor returns the same recent sold listings as JSON without an eBay account.
On eBay, tick “Sold items” in the search filters to view completed sales one page at a time. To export them in bulk, the free Apify plan’s monthly credit covers roughly 1,400 sold listings with this actor.
About 90 days. Older sales don’t appear in eBay search, so schedule runs if you need a longer history.
No. eBay doesn’t publish it in search results or on the item page. The actor flags those sales with bestOfferAccepted instead of guessing.
The actor collects publicly visible sold-listing data and no buyer data. Follow eBay’s terms and data protection laws such as GDPR, and don’t use the data to profile individual sellers. This isn’t legal advice.
Pick a product you’re about to buy or list, enter it in the eBay Sold Listings API, turn on price statistics and set maxItems to 50. You’ll have a median sold price in under a minute. More details are on the actor page.