Auction house sold prices (Goldin, Fanatics Collect, Pristine Auction, MySlabs)
GET /goldin/sold, /fanatics/sold, /pristine/sold and /myslabs/sold return graded card and collectibles auction results by keyword, with the price the buyer paid (buyer's premium included), sale date, sale type, grading company and grade.
Four endpoints for realized prices from the big graded card and collectibles auction houses. All four share one response format, use your normal API key, monthly quota and rate limit, and work on every plan. Each call counts as one request, and failed calls are never charged.
| Endpoint | Source | What you get |
|---|---|---|
GET /goldin/sold | Goldin | Sold lots with hammer price, buyer's premium, final price, bid count and sale type |
GET /fanatics/sold | Fanatics Collect (formerly PWCC) | Sales with price, sale type, grading company, grade, cert number and year |
GET /pristine/sold | Pristine Auction | Ended lots with the realized price, end time and sale type |
GET /myslabs/sold | MySlabs | Sold slabs with price (1% buyer's premium included), shipping, sold day and sale type |
price is what the buyer paid in US dollars. Where the house charges a buyer's premium (Goldin, Fanatics Collect
auctions, MySlabs) it is included, so prices compare directly with eBay sold prices.
/goldin/soldcost 1 requestcurl "https://api.ebaysoldlistingsapi.com/goldin/sold?keyword=1999+pokemon+base+set+holo+charizard+psa+8" \
-H "Authorization: Bearer YOUR_API_KEY"The other three work the same way: replace goldin with fanatics, pristine or myslabs.
import requests
for house in ["goldin", "fanatics", "pristine", "myslabs"]:
response = requests.get(
f"https://api.ebaysoldlistingsapi.com/{house}/sold",
headers={"Authorization": "Bearer YOUR_API_KEY"},
params={"keyword": "michael jordan 1986 fleer psa 8"},
timeout=60,
)
response.raise_for_status()
data = response.json()
print(house, data["totalItems"], "sales, median", (data["summary"] or {}).get("median"))Parameters
| Parameter | Values | Default |
|---|---|---|
keyword | Card, player, set and grade, up to 300 characters | Required |
sortBy | recent, price_desc, price_asc | recent |
page | Goldin 1 to 100, Fanatics Collect 1 to 200, Pristine 1 to 50, MySlabs 1 only | 1 |
deep | MySlabs only: true merges several result sets for a few hundred sales | false |
Page sizes: 50 sales (Goldin, Fanatics Collect), 60 (Pristine Auction), up to 72 (MySlabs). Keep requesting the next
page while hasNextPage is true.
MySlabs returns one page per search. Add deep=true to merge the results of every sort order and price range for the
same keyword (a few hundred distinct sales, about 10 seconds). Deep MySlabs calls count as one request each and are
limited to about 3 per minute per account.
Response
{
"keyword": "1999 pokemon base set holo charizard psa 8",
"page": 1,
"pageSize": 50,
"marketplace": "goldin",
"sortBy": "recent",
"totalResults": 178,
"totalItems": 50,
"hasNextPage": true,
"items": [
{
"saleId": "202603-2220-5857-fc7a8619-40e8-4bda-b1d3-45fbca31e177",
"url": "https://goldin.co/item/1999-pokemon-base-set-holo-4-charizarditxlj",
"title": "1999 Pokemon Base Set Holo #4 Charizard - PSA NM-MT 8",
"price": 1587.22,
"hammerPrice": 1301,
"buyersPremiumPercent": 22,
"shippingPrice": null,
"currency": "USD",
"soldAt": "2026-10-19T03:28:38.000Z",
"saleType": "Weekly",
"bids": 34,
"gradingService": "PSA",
"grade": "8",
"certNumber": null,
"year": 1999,
"category": null,
"imageUrl": null
}
],
"summary": { "count": 50, "currency": "USD", "median": 6133.55, "mean": 81155.21, "min": 350.14, "max": 3080500, "p25": 1235.56, "p75": 31262.5, "avgShipping": null }
}pricenumberhammerPricenumberbuyersPremiumPercentnumbershippingPricenumbersoldAtstringsaleTypestringFIXED, WEEKLY, PREMIER (Fanatics Collect), Weekly, Elite, Thematic (Goldin), Fixed price, Auction (MySlabs).bidsnumbergradingServicestringgradestringcertNumberstringurlstringsummaryobjectThe houses match keywords loosely, the way their own search boxes do: the search above also returns other Charizard
cards and grades, which is why its price range is wide. Check title, grade and year (or add the set, number and
grade to the keyword) before you use a price as a comp for one exact card.
Coverage
| Source | Coverage |
|---|---|
| Fanatics Collect | 5.5 million sales back to 2008, including PWCC history; sorted by sold date or price |
| Goldin | Every sold lot that matches the keyword, sorted by sold date or price |
| Pristine Auction | Ended lots that match the keyword |
| MySlabs | The most recent sold slabs for the keyword (up to 72), or a few hundred with deep=true |
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_params | Missing keyword, a page out of range, or a MySlabs page above 1 |
| 402 | quota_exceeded | Monthly quota reached |
| 429 | rate_limited | Per-minute limit reached; retry after the Retry-After seconds |
| 502, 503, 504 | upstream_blocked, server_busy, upstream_timeout | The house did not answer this time; retry after a few seconds |
TCGplayer sales and listings
GET /tcgplayer/sold returns TCGplayer completed sales with optional market price history, and GET /tcgplayer/listings returns current listings, for Pokemon, Magic, Yu-Gi-Oh, One Piece and other trading cards.
Batch jobs
POST /scrape/batch runs up to 100 keywords in one asynchronous job. Poll it, then read the results as JSON or one CSV.