CompSniper Docs

PSA Population and Graded Card Prices API

PSA graded card prices by grade, population reports for a single card or a whole set, card search and a full list of PSA sets per game, with one API key.

CompSniper has four PSA endpoints for graded trading cards:

EndpointWhat you get
GET /v1/psa/searchFind a card and its PSA specId
GET /v1/psa/cardPrices by grade, recent sales and the population report for one card
GET /v1/psa/setsFind a PSA set, or list every set for a game, with its headingId
GET /v1/psa/setThe population of every card in a set, for every grade, in one call

All four use the same API key, per-minute limit, monthly allowance and purchased credits as the eBay endpoints. Each call counts as one request, and failed calls are never charged.

Find a card

Search by card name, set and number. Each match comes back with the specId you pass to /v1/psa/card.

curl --fail-with-body \
  -H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
  "https://api.compsniper.com/v1/psa/search?keyword=charizard+base+set&count=5"
ParameterValuesDefault
keywordCard name, set, number, up to 200 charactersRequired
count1 to 20 matches10
page1 to 501
Search response (shortened)
{
  "keyword": "charizard base set",
  "marketplace": "psa",
  "totalResults": 57628,
  "totalItems": 5,
  "items": [
    {
      "specId": "5217539",
      "description": "2019 Pokemon Chinese Sun & Moon All Stars Collection 032 Charizard GX Set A",
      "subject": "Charizard GX Set A",
      "cardNumber": "032",
      "setName": "Pokemon Chinese Sun & Moon All Stars Collection",
      "year": "2019",
      "category": "Tcg Cards"
    }
  ]
}

Prices and population for one card

Send a specId from the search, or a keyword and CompSniper picks the best match (other close matches are listed in otherMatches).

curl --fail-with-body \
  -H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
  "https://api.compsniper.com/v1/psa/card?specId=5217539&count=20"
ParameterValuesDefault
specIdPSA spec ID (digits)Required unless keyword is sent
keywordCard name, set, number, up to 200 charactersNone
count0 to 50 recent sales in items10
timeRangeMonths of sales to include, 0 to 120 (0 = all available)0
gradeA PSA grade from 1 to 10 (half grades allowed) or raw, to filter itemsAll grades

The response has:

  • priceByGrade: for each grade, the number of sales, average, minimum, maximum and latest price.
  • population: total graded, the gem rate (share graded 10) and the count for every grade, with copies graded with a qualifier (for example 9 OC) counted separately in withQualifier.
  • items: recent sales with date, price, sale type, grading company, grade, cert number and listing link.
  • summary: median, mean, range and quartiles of the returned sales.
Card response (shortened)
{
  "card": {
    "specId": "5217539",
    "subject": "CHARIZARD GX",
    "cardNumber": "#032",
    "setName": "POKEMON CHINESE SUN & MOON ALL STARS COLLECTION",
    "year": "2019"
  },
  "priceByGrade": [
    { "grade": "10", "sales": 1, "averagePrice": 48, "minPrice": 48, "maxPrice": 48, "latestPrice": 48 }
  ],
  "population": {
    "total": 26,
    "gemRate": 69.23,
    "grades": [{ "grade": "10", "count": 18, "withQualifier": 0 }]
  },
  "items": [
    {
      "saleDate": "2025-04-05T00:04:00.000Z",
      "salePrice": 2.25,
      "saleType": "Auction",
      "gradingCompany": "UNGRADED",
      "grade": null,
      "certNumber": null,
      "url": "https://www.ebay.com/itm/365490372146"
    }
  ]
}

Every set for a game

Send a game to list every PSA set for that game, newest first, and page through all of them. Add a keyword or year to narrow the list. Without a game, a keyword searches set names across all games.

curl --fail-with-body \
  -H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
  "https://api.compsniper.com/v1/psa/sets?game=pokemon&count=100&page=1"
ParameterValuesDefault
gameSee the list belowNone
keywordWords in the set name, at least 2 charactersRequired unless game is sent
year4-digit yearAll years
count1 to 100 sets per page25
page1 to 10001

Games: pokemon, one-piece, magic, yugioh, dragon-ball, lorcana, digimon, weiss-schwarz, union-arena, flesh-and-blood, star-wars-unlimited, cardfight-vanguard, duel-masters, battle-spirits, final-fantasy, gundam, shadowverse, riftbound, grand-archive and wixoss.

Keep requesting the next page while hasNextPage is true. totalResults is the number of sets that match.

Sets response (shortened)
{
  "keyword": "151",
  "marketplace": "psa",
  "game": "pokemon",
  "page": 1,
  "hasNextPage": true,
  "totalResults": 21,
  "totalItems": 3,
  "items": [
    {
      "headingId": "249038",
      "name": "Pokemon German Mew de-151",
      "year": "2023",
      "url": "https://www.psacard.com/pop/tcg-cards/2023/pokemon-german-mew-de-151/249038",
      "gradedTotal": 9947
    }
  ]
}

Population of a whole set

Send a set's headingId (from /v1/psa/sets), or the set's PSA population page link as url. One call returns every card in the set.

curl --fail-with-body \
  -H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
  "https://api.compsniper.com/v1/psa/set?headingId=57801"
ParameterValuesDefault
headingIdPSA set ID from /v1/psa/setsRequired unless url is sent
urlThe set's PSA population page, for example https://www.psacard.com/pop/tcg-cards/1999/pokemon-game/57801None

Each card has its number, English name, variety, PSA specId and its population for every grade (Authentic, then 1 to 10 including half grades). totals is the same breakdown for the whole set. Large sets can take 10 to 20 seconds.

Set response (shortened)
{
  "set": { "headingId": "57801", "name": "Pokemon Game", "year": "1999", "gradedTotal": 1154473 },
  "totalCards": 490,
  "totals": {
    "total": 1158021,
    "grades": [{ "grade": "9", "count": 278101, "withQualifier": 214 }, { "grade": "10", "count": 112472, "withQualifier": 0 }]
  },
  "items": [
    {
      "specId": "544021",
      "cardNumber": "1",
      "name": "Alakazam-Holo",
      "variety": null,
      "population": {
        "total": 20791,
        "grades": [{ "grade": "9", "count": 3695, "withQualifier": 2 }, { "grade": "10", "count": 457, "withQualifier": 0 }]
      }
    }
  ]
}

Errors and pacing

StatuscodeMeaning
400invalid_paramsA parameter is missing or invalid; the message says which
502upstream_blockedPSA did not complete this call; retry after a short pause
503server_busyPSA is busy right now; retry after retry_after seconds

Failed calls are not charged. For bulk pulls, spread calls out (about one per second) rather than sending large parallel bursts. Results are kept for a short time, so repeating the same call is fast.

On this page