OrbTop

PSA Auction Prices Realized Scraper - Sold Comps

ECOMMERCESPORTS

PSA Auction Prices Realized Scraper

Scrape PSA Auction Prices Realized (APR) — sold-comp price data for PSA-graded sports cards, Pokemon, and trading card games. Returns sale price, date, auction house, grade, cert number, and sub-grades when available.

The output schema is joinable with PSA Population Report data via card_id, enabling full scarcity-plus-price analysis.

What you get

Each record represents one sold lot:

Field Description
apr_id Unique PSA APR sale record ID
card_id PSA internal card spec ID (joinable with pop data)
cert_number PSA cert number of the specific copy sold
category Card category (sports / pokemon / tcg / non-sport)
sport Sport tag (baseball / basketball / football / etc.)
year Card year
brand Brand / manufacturer
set_name Set name
card_number Card number within the set
player_or_subject Player name or card subject
parallel_or_variant Parallel or variant (refractor / autograph variant / etc.)
grade PSA grade label (PSA 10 / PSA 9 / etc.)
grade_numeric Numeric grade value
qualifier Grade qualifier flag (OC / PD / MK / etc.)
auction_house Where the comp sold (eBay / Goldin / Heritage / PWCC / etc.)
listing_type Listing type (auction / fixed-price / best-offer)
sold_price Final sale price
currency Sale currency (USD)
sold_at Sale timestamp (ISO 8601)
autograph True if autographed card
memorabilia True if card contains memorabilia (jersey / patch / etc.)
source_url Original auction listing URL
image_url Card image URL from the APR listing

Sub-grade fields (subgrade_centering, subgrade_corners, subgrade_edges, subgrade_surface) are populated when the Include Sub-Grades option is enabled.

Modes

Search (recommended for targeted research)

Search PSA APR by player name, set, or keyword:

{
  "mode": "search",
  "searchQuery": "mike trout rookie",
  "maxItems": 100
}

APR Archive Walk

Walk all APR data by category or sport:

{
  "mode": "apr_walk",
  "category": "pokemon",
  "maxItems": 500
}

Category options: sports, pokemon, tcg, non-sport (blank = all)

Sport filter (within sports category): baseball, basketball, football, hockey, soccer, golf, boxing

Specific Card URLs

Fetch sales data for specific PSA spec pages directly:

{
  "mode": "card_urls",
  "cardUrls": [
    "https://www.psacard.com/spec/psa/887339"
  ]
}

Filtering options

  • Grade Filter — restrict to a specific grade (e.g. "10", "9", "8.5")
  • Year From / Year To — filter cards by production year
  • Include Sub-Grades — capture centering / edges / corners / surface sub-grades (costs one extra fetch per card)

Joining with PSA Population data

The card_id field is the PSA spec ID — the same identifier used by PSA's pop report. Joining APR output to pop data gives you scarcity context alongside realized prices:

SELECT
  apr.card_id,
  apr.set_name,
  apr.player_or_subject,
  apr.grade,
  apr.sold_price,
  apr.sold_at,
  pop.psa_10_count,
  pop.total_graded
FROM apr_sales AS apr
JOIN psa_population AS pop
  ON apr.card_id = pop.spec_id
 AND apr.grade_numeric = 10

Notes

  • PSA APR is behind Cloudflare. The actor uses a residential proxy with Cloudflare bypass — a residential proxy entitlement is required.
  • Sale history is fetched from PSA's JSON API. Each card spec gets a paginated API call.
  • maxItems limits total output records (sale events), not the number of card specs scraped.
  • Default timeout is 4 hours. Large APR archive walks may require extended run time.