If you search "ebay sold listings api" you land on a decade of Stack Overflow answers that all say the same thing: call findCompletedItems on the Finding API with SoldItemsOnly=true. That call has been dead since February 2025, when eBay shut the Finding API down. This is what the options look like now, with code for the one that actually returns sold prices.
Disclosure up front: I build trawl, which is the last option below. The first four are eBay's own and the scrapers, and I've tried to describe them fairly.
What findCompletedItems did
One GET with keywords, an optional category and a SoldItemsOnly filter, and you got back up to 100 completed listings per page with the final price, end time and condition. It was the backbone of every pricing tool, flipping spreadsheet and resale app that needed to know what things actually sell for. eBay restricted it in 2020 and removed it with the rest of the Finding API in 2025.
Option 1: the Browse API (no)
eBay's replacement for Finding is the Browse API. It searches live listings. There is no sold filter, no completed filter and no way to reach ended items. If a tutorial tells you to use Browse for sold prices, it was written by someone who didn't run it.
Option 2: the Marketplace Insights API (if they let you)
This is the official sold-data API: item_sales/search returns the last 90 days of sales for a keyword or category. The catch is access. It is a "limited release" API, you apply through developer support with a business case, and most applicants hear nothing. If you can get it, it's the right answer for 90 days of data. Comparison with what you'll read below is at trawl vs the Marketplace Insights API.
Option 3: Terapeak (not an API)
Terapeak lives inside Seller Hub and shows up to three years of sold history in a browser. It has no API, no export beyond the page you're looking at, and it needs a seller account. It is good for a human looking up one item and useless for a program.
Option 4: scrapers
Apify, RapidAPI and GitHub have dozens of scrapers that load eBay's sold-listings search page and parse it. They work until they don't: the page is behind a login wall for sold results more often each year, the HTML changes, and you only ever see the 90 days the page shows. For a one-off pull of a few hundred rows they're fine. For anything you run daily, you are now maintaining a scraper.
Option 5: a sold-listings database with an API
The approach that holds up is to query a database of completed sales rather than eBay's pages. trawl does that for ebay.com and ebay.co.uk: one GET returns every matching completed sale, newest first, with the final price, sale date, condition, shipping, buying format and item id, from a database of 400M+ sales that reaches back past the 90 days eBay shows. There's a free tier with no card.
The old call, rewritten:
# pip install requests
import os, requests
r = requests.get(
"https://api.trawl.dev/ebay/v1/sold",
headers={"x-api-key": os.environ["TRAWL_API_KEY"]},
params={
"query": "iphone 15 pro 256gb", # every word must appear in the title
"category": "9355", # Cell Phones & Smartphones, optional
"condition": "used", # new, used, parts, other
"max_pages": 3, # 100 results per page, up to 20
},
timeout=30,
)
r.raise_for_status()
sold = r.json()
print(f"{sold['count']} sold listings, {sold['credits_charged']} credits")
for s in sold["results"][:5]:
print(s["date_sold"][:10], s["currency"], s["sale_price"], s["title"][:60])
A result row looks like this:
{
"title": "Apple iPhone 15 Pro 256GB Unlocked",
"sale_price": 525.00,
"shipping_price": 0,
"currency": "$",
"condition": "used",
"condition_raw": "Pre-Owned",
"buying_format": "Buy It Now",
"date_sold": "2026-10-14T00:00:00Z",
"item_id": "...",
"item_link": "https://www.ebay.com/itm/..."
}
Three things that map onto what people used findCompletedItems for:
-
Price history past 90 days. Add
date_fromanddate_to(YYYY-MM-DD) and the same query answers for last spring. The sold listings history guide walks a year. -
A whole category. Send
categorywith noqueryand you get every sale in it, newest first, and anext_cursorto keep walking past 2,000 results. That was never possible with findCompletedItems. -
Item specifics.
attr=Grade:10&attr=Professional Grader:PSAfilters on the listing's own specifics, which is how card and collectible pricing works.
The field-by-field translation of a findCompletedItems request, in Python, Node and Go, is in the findCompletedItems alternative guide. The same search also runs as an Actor on Apify if you'd rather pay per result there than hold an API key.
Which one
- You have Marketplace Insights access and 90 days is enough: use it, it's official.
- You need one lookup by hand: Terapeak in Seller Hub.
- You need a few hundred rows once: any scraper.
- You need sold prices in a program, daily, with history, or by category: a database-backed API is the only option that doesn't turn into maintenance.
Questions about the data or the API are welcome in the comments; I'll answer the ones about the competition too.
Top comments (0)