Quickstart
Make your first CompSniper eBay sold-listings request with cURL, Python, JavaScript, Java, Go, Ruby, or C#.
1. Create an API key
Create a free account, then copy the key from Dashboard > API keys. Keys begin with
cs_live_. Keep the complete key on your server and out of browser code and public repositories.
2. Choose a marketplace and send a keyword
Replace cs_live_REPLACEWITHYOURKEY in one example.
CompSniper searches ebay.com by default. Set ebaySite on every request when you need a local
marketplace. For example, a UK seller should send ebaySite=ebay.co.uk, while an Australian seller
should send ebaySite=ebay.com.au. The supported values are ebay.com, ebay.co.uk, ebay.de,
ebay.fr, ebay.it, ebay.es, ebay.ca, and ebay.com.au. The response shape stays the same.
curl --fail-with-body \
-H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
"https://api.compsniper.com/v1/scrape?keyword=iphone+15+pro&count=10&ebaySite=ebay.com"Change only the marketplace value for another country:
curl --fail-with-body \
-H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
"https://api.compsniper.com/v1/scrape?keyword=iphone+15+pro&count=10&ebaySite=ebay.co.uk"3. Read the response
A successful response includes:
items: valid, deduplicated completed eBay listings.summary: cleaned median, mean, p25, p75, min, max, shipping average, and sample size.rawMedianandrawSampleCount: evidence after optional exact-section parsing but before relevance cleanup.hasNextPage: whether another page is available.X-Usage-Remaining: account requests left in the current billing period.X-Rollover-Balance: unused requests carried from a full-price upgrade until the next renewal.X-Credit-Balance: non-expiring purchased credits still available.X-Credit-Source:rollover,subscription, orcredits, showing what paid for this successful request.
Carried-over requests are used first, then the current monthly allowance. When both reach zero,
CompSniper automatically uses purchased credits. To preserve monthly quota for another integration, send
X-Credit-Source: credits and the request will use a purchased credit first (if your credits run out, it
falls back to your monthly allowance instead of failing). Purchase credits from
Dashboard > Subscription for $5 per 1,000. Enter any amount from
1,000 to 1,000,000 in increments of 100. Credits never expire and
failed searches are not charged.
Current active listings
Set sold=false to inspect current asking prices and visible demand signals instead of completed sales:
curl --fail-with-body \
-H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
"https://api.compsniper.com/v1/scrape?keyword=iphone+14&sold=false&count=10"Active rows use listingType: "active" and replace soldPrice, soldCurrency, endedAt, and
bestOfferAccepted with currentPrice, currentPriceMax, currentCurrency, watcherCount,
unitsSold, acceptsOffers, and timeLeft. Watcher, units-sold, and time-left values are null when eBay
does not display them on the search card. summary is null because an asking-price result is not a sold
price distribution.
{
"listingType": "active",
"currentPrice": "289.99",
"currentCurrency": "USD",
"watcherCount": 37,
"unitsSold": 622,
"acceptsOffers": true,
"timeLeft": null
}Optional eBay exact section
Set exactMatch=true when you want CompSniper to remove the section that eBay explicitly labels
Results matching fewer words. This happens during parsing, before deterministic pricing checks and
semantic cleanup:
curl --fail-with-body \
-H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
"https://api.compsniper.com/v1/scrape?keyword=garmin+8612xsv&exactMatch=true"exactMatch defaults to false, so existing integrations and broad searches remain unchanged.
When eBay does not emit the boundary, enabling it changes nothing. When the boundary is present,
CompSniper removes every later card and reports hasNextPage=false because the exact section has ended.
The option follows eBay's own section split; it does not independently prove that every retained card is
the requested product. Keep relevance=true for the additional pricing and semantic checks.
Optional facets and EU seller type
Use aspectFilter with the human-readable names shown in eBay's refinement sidebar. Values can be a
string, a pipe-delimited string, or an array. Use sellerType=private or sellerType=business on
ebay.de, ebay.fr, ebay.it, or ebay.es:
curl --get --fail-with-body \
-H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
--data-urlencode "keyword=iphone 15 pro" \
--data-urlencode 'aspectFilter={"Model":"Apple iPhone 15 Pro","Storage Capacity":"256 GB"}' \
"https://api.compsniper.com/v1/scrape"
curl --get --fail-with-body \
-H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
--data-urlencode "keyword=iphone 14" \
--data-urlencode "ebaySite=ebay.de" \
--data-urlencode "sellerType=private" \
"https://api.compsniper.com/v1/scrape"Seller filtering is ignored on the four marketplaces that do not expose seller classification. Returned
EU rows include sellerType when eBay labels the seller. conditionId is a best-effort numeric mapping
of known localized condition labels; always retain the original condition string as the source value.
Baseline listing hygiene
Every search removes malformed navigation and recommendation rows before applying optional relevance
cleanup. Sold rows must have a real eBay item ID, a matching /itm/ URL, a positive sold price, and a
sold date. Active rows must have the same ID and URL checks plus a positive current price. Duplicate item
IDs are returned once.
This baseline validation also applies when relevance=false. That setting disables query-aware pricing
checks and semantic cleanup, so accessories and nearby models can remain, but it never returns malformed
non-listing rows. count is a ceiling, not a guaranteed row count, so a response can contain fewer items
after baseline validation, date filters, or relevance cleanup.
With relevance cleanup enabled, deterministic title checks remove explicit pricing mismatches before the batched semantic classifier runs. These include unrequested lots, multipacks, bundles, selection listings, modified or non-original items, prototypes, damaged or parts-only units, standalone accessories, and explicitly conflicting years, capacities, sizes, quantities, grading details, or catalog numbers. If the keyword explicitly requests one of those cases, CompSniper keeps it.
{
"keyword": "iphone 15 pro",
"page": 1,
"totalItems": 10,
"hasNextPage": true,
"summary": {
"count": 10,
"currency": "USD",
"median": 749.99,
"p25": 699.0,
"p75": 829.5
},
"items": [
{
"itemId": "123456789",
"title": "Apple iPhone 15 Pro 256GB",
"soldPrice": "749.99",
"soldCurrency": "USD",
"endedAt": "2026-08-29"
}
]
}Running many searches at once
The single search above is built for interactive, one-keyword-at-a-time calls. If you need to run a large
list of keywords (dozens or hundreds), do not fire them all at /v1/scrape in parallel. Every search pulls
live data from eBay, and eBay pushes back on bursts, so the overflow comes back as 429 rate_limited or
503 server_busy. Submit the whole list as one async job instead: it is paced for you and every result is
returned, no drops.
curl --fail-with-body -X POST "https://api.compsniper.com/v1/scrape/jobs" \
-H "Authorization: Bearer cs_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"queries": ["iphone 15 pro 256gb", "iphone 15 pro 1tb"], "options": {"exactMatch": true}}'
# -> { "jobId": "abc123", "status": "queued", "resultsUrl": "/v1/scrape/jobs/abc123" }curl --fail-with-body "https://api.compsniper.com/v1/scrape/jobs/abc123" \
-H "Authorization: Bearer cs_live_YOUR_KEY"Send up to 100 keywords per job, and submit the next job once the current one is done. Each keyword is searched independently and comes back with its own price summary, so different variants stay separate. See rate limits for the full guidance on high-volume usage.
Next, review authentication, rate limits, pagination, and bulk search before running production jobs.