curl --request GET \
--url https://scrapebadger.com/v1/ebay/completed \
--header 'x-api-key: <api-key>'import requests
url = "https://scrapebadger.com/v1/ebay/completed"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://scrapebadger.com/v1/ebay/completed', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://scrapebadger.com/v1/ebay/completed",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://scrapebadger.com/v1/ebay/completed"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://scrapebadger.com/v1/ebay/completed")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://scrapebadger.com/v1/ebay/completed")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"query": "<string>",
"domain": "<string>",
"category_id": "<string>",
"sold": true,
"results": [
{
"position": 123,
"item_id": "<string>",
"product_id": "<string>",
"title": "<string>",
"url": "<string>",
"image": "<string>",
"price": {
"value": 123,
"currency": "<string>",
"symbol": "<string>",
"raw": "<string>"
},
"original_price": {
"value": 123,
"currency": "<string>",
"symbol": "<string>",
"raw": "<string>"
},
"discount_percent": 123,
"currency": "<string>",
"condition": "<string>",
"brand": "<string>",
"buying_format": "<string>",
"is_auction": true,
"bids": 123,
"time_left": "<string>",
"current_bid": {
"value": 123,
"currency": "<string>",
"symbol": "<string>",
"raw": "<string>"
},
"shipping": "<string>",
"shipping_cost": {
"value": 123,
"currency": "<string>",
"symbol": "<string>",
"raw": "<string>"
},
"free_shipping": true,
"location": "<string>",
"returns": "<string>",
"sold_count": 123,
"sold_date": "2 Jul 2026",
"sold_date_at": "2026-07-02",
"watchers": 123,
"coupon": "<string>",
"rating": 123,
"ratings_total": 123,
"seller_name": "<string>",
"seller_feedback_percent": 123,
"seller_feedback_score": 123,
"program_badge": "<string>",
"is_sponsored": true
}
],
"facets": {},
"pagination": {
"current_page": 123,
"per_page": 123,
"total_pages": 123,
"total_results": 123,
"has_more": true
},
"scraped_utc": 123,
"scraped_at": "<string>"
}Completed / Sold Listings
Search eBay completed (sold) listings — the closing prices buyers actually paid.
curl --request GET \
--url https://scrapebadger.com/v1/ebay/completed \
--header 'x-api-key: <api-key>'import requests
url = "https://scrapebadger.com/v1/ebay/completed"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://scrapebadger.com/v1/ebay/completed', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://scrapebadger.com/v1/ebay/completed",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://scrapebadger.com/v1/ebay/completed"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://scrapebadger.com/v1/ebay/completed")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://scrapebadger.com/v1/ebay/completed")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"query": "<string>",
"domain": "<string>",
"category_id": "<string>",
"sold": true,
"results": [
{
"position": 123,
"item_id": "<string>",
"product_id": "<string>",
"title": "<string>",
"url": "<string>",
"image": "<string>",
"price": {
"value": 123,
"currency": "<string>",
"symbol": "<string>",
"raw": "<string>"
},
"original_price": {
"value": 123,
"currency": "<string>",
"symbol": "<string>",
"raw": "<string>"
},
"discount_percent": 123,
"currency": "<string>",
"condition": "<string>",
"brand": "<string>",
"buying_format": "<string>",
"is_auction": true,
"bids": 123,
"time_left": "<string>",
"current_bid": {
"value": 123,
"currency": "<string>",
"symbol": "<string>",
"raw": "<string>"
},
"shipping": "<string>",
"shipping_cost": {
"value": 123,
"currency": "<string>",
"symbol": "<string>",
"raw": "<string>"
},
"free_shipping": true,
"location": "<string>",
"returns": "<string>",
"sold_count": 123,
"sold_date": "2 Jul 2026",
"sold_date_at": "2026-07-02",
"watchers": 123,
"coupon": "<string>",
"rating": 123,
"ratings_total": 123,
"seller_name": "<string>",
"seller_feedback_percent": 123,
"seller_feedback_score": 123,
"program_badge": "<string>",
"is_sponsored": true
}
],
"facets": {},
"pagination": {
"current_page": 123,
"per_page": 123,
"total_pages": 123,
"total_results": 123,
"has_more": true
},
"scraped_utc": 123,
"scraped_at": "<string>"
}sold set to true
on the response envelope. This is the data resellers, flippers and pricing tools
rely on, since asking prices alone don’t reflect what items actually sell for.
Query Parameters
/v1/ebay/markets for all supported values.Examples: com, co.uk, de, fr, com.au/v1/ebay/categories to look up ids.1 - 1000.Use pagination.has_more to know when to stop — eBay re-serves its last
page if you ask past the end, so this API returns an empty page there.60, 120, or 240.| Value | Description |
|---|---|
best_match | Best match (default) |
ending_soonest | Ended soonest first |
newly_listed | Most recently ended |
price_low_to_high | Lowest sold price first |
price_high_to_low | Highest sold price first |
new, open_box, refurbished, used, for_parts).Trading cards also accept graded and ungraded — eBay’s card conditions for
slabbed (PSA / BGS / CGC) versus raw cards. Pricing a raw card against sales
that include slabs skews the average badly, so price the two separately.| Value | Description |
|---|---|
domestic | Only items located in this marketplace’s own country (domain=fr → France only) |
worldwide | Items from every country |
location=domestic removes both.Response
Identical shape to/v1/ebay/search, except sold is true, each result’s price reflects the final sold price, and each result carries a sold_date.
true for completed/sold listings.SearchResult shape as active search).Show SearchResult object
Show SearchResult object
value, currency, symbol, raw.Buy It Now, Auction, or Best Offer.value, currency, symbol, raw; mirrors price. Null for fixed-price listings.Aug 19, 2026. Localized on non-English marketplaces (e.g. Verkauft 5. Okt. 2024), nullable.sold_date, e.g. 2026-08-19. Null when the marketplace’s date format is not English.null. eBay renders its “Sponsored” badge into every card as anti-scraping bait, so promoted placements cannot be distinguished from organic results.current_page, per_page, total_results, has_more.total_results is populated (the sold results page carries a match count). total_pages may be null — page with has_more rather than a fixed page total.Example Response
{
"query": "nintendo switch",
"domain": "com",
"sold": true,
"results": [
{
"position": 1,
"item_id": "256987654321",
"title": "Nintendo Switch (OLED Model) - Used",
"url": "https://www.ebay.com/itm/256987654321",
"image": "https://i.ebayimg.com/images/g/xyz/s-l500.jpg",
"price": { "value": 260.0, "currency": "USD", "symbol": "$", "raw": "$260.00" },
"condition": "Pre-Owned",
"buying_format": "Auction",
"is_auction": true,
"bids": 14,
"current_bid": { "value": 260.0, "currency": "USD", "symbol": "$", "raw": "$260.00" },
"shipping": "Free shipping",
"location": "United States",
"sold_date": "Aug 19, 2026",
"sold_date_at": "2026-08-19",
"seller_name": "gamerdeals99",
"is_sponsored": null
}
],
"facets": {},
"pagination": { "current_page": 1, "per_page": 60, "total_pages": null, "total_results": 34000, "has_more": true },
"scraped_at": "2026-08-20T12:00:00Z"
}
Fetching every sold listing
has_more is the stop signal for bulk extraction. Increment page while it is true:
page, all_sold = 1, []
while True:
r = requests.get(
"https://scrapebadger.com/v1/ebay/completed",
params={"query": "iphone 13", "per_page": 240, "page": page},
headers={"X-API-Key": API_KEY},
).json()
all_sold += r["results"]
if not r["results"] or not r["pagination"]["has_more"]:
break
page += 1
has_more: false, but a
client that ignores has_more and retries forever will keep spending credits.per_page=240 (~26,000 listings).
Use the largest per_page you can: each request costs 5 credits regardless of page
size, so per_page=240 is about 8x cheaper per listing than the default.
Authorizations
Query Parameters
Search keywords.
eBay marketplace domain TLD or alias (com, co.uk, de, fr, ...).
Restrict results to a category id.
Page number for paginated results.
1 <= x <= 1000Results per page. Clamped to 60, 120 or 240.
1 <= x <= 240Sort order for results.
best_match, ending_soonest, newly_listed, price_low_to_high, price_high_to_low Item condition. graded / ungraded are eBay's trading-card conditions — slabbed (PSA/BGS/CGC) vs raw — so a card can be priced separately from its slabs.
new, open_box, refurbished, used, for_parts, graded, ungraded Minimum price filter in the marketplace's local currency.
x >= 0Maximum price filter in the marketplace's local currency.
x >= 0Item location. domestic returns only items located in this marketplace's own country (domain=fr → France only); worldwide widens to every country. Foreign listings are priced in the marketplace's currency after eBay CONVERTS them, so domestic is also how you get untouched native sale prices.
domestic, worldwide 
