eBay sold listings
GET /v1/ebay/sold searches one page of eBay US sold listings by keyword, with condition and price filters, and returns JSON.
GET
https://api.soldgraph.com/v1/ebay/soldSearch eBay US sold listings by keyword. Each call returns one page of results, not a full sales history.
Moving off eBay's retired findCompletedItems? See findCompletedItems replacement.
| Parameter | Type | Default | Description |
|---|---|---|---|
q | string | Required | Search keywords, 1–200 characters, as you'd type them into the marketplace's search box. Be specific: model, size, grade, edition. |
page | integer, 1–100 | 1 | Source page to fetch. On Poshmark, Mercari and Depop, pages after 1 also need cursor. |
min_price | integer, 0–1000000 | Lowest price, in whole US dollars. Optional. Must not be more than max_price. You can send it without max_price. | |
max_price | integer, 0–1000000 | Highest price, in whole US dollars. Optional. You can send it without min_price. | |
marketplace | ebay | ebay | Optional. If sent, it must be ebay. |
country | us | us | Only us is supported. |
condition | One or more of new, open_box, refurbished, used, for_parts, comma-separated | eBay's own condition groups. Send one or more, separated by commas, like new,open_box. new is Brand New, open_box is Open Box or New (Other), refurbished is every refurbished grade, used is Pre-Owned and for_parts is Parts Only. eBay applies the filter. |
curl -G https://api.soldgraph.com/v1/ebay/sold \ -H "Authorization: Bearer $SOLDGRAPH_KEY" \ --data-urlencode "q=sony wh-1000xm5" \ -d page=1The first call usually returns 202 and a job to poll. Search jobs covers polling, retries and pagination.
#Filters
conditiontakes one or more of eBay's condition groups, separated by commas, likenew,open_box. The groups arenew(Brand New),open_box(Open Box or New (Other)),refurbished(every refurbished grade),used(Pre-Owned) andfor_parts(Parts Only).min_priceandmax_priceare whole US dollars. You can send either one alone.
eBay applies the filters, so reported_total counts only matching listings.
#Example response
Response
{ "request_id": "00000000-0000-4000-8000-000000000001", "status": "complete", "credits": 1, "cached": false, "result": { "provider": "ebay", "country": "us", "query": "sony wh-1000xm5", "page": 1, "page_size": 40, "count": 1, "reported_total": 1, "next_page": null, "next_cursor": null, "collected_at": "2026-09-23T14:02:11Z", "schema_version": 1, "completeness": "provider_page_only", "data": [ { "id": "123456789012", "title": "Example eBay listing", "link": "https://www.ebay.com/itm/123456789012", "displayed_price": { "amount": 189, "currency": "USD" }, "displayed_price_text": "$189.00", "displayed_shipping": { "amount": 9.99, "currency": "USD" }, "shipping_text": "+$9.99 delivery", "sold_date": "2026-09-21", "sold_date_text": "Sep-21 14:35", "condition": "Pre-Owned", "seller_text": "sonyfan_outlet (2,418) 99.6%", "brand": null, "size": null, "image": "https://i.ebayimg.com/images/g/example/s-l500.jpg", "price": null, "shipping": null, "sold_at": null, "took_offer": null } ], "field_notes": "Unverified fields are null. Displayed prices are not verified accepted-offer prices." }}| Field | Type | Description |
|---|---|---|
request_id | string | ID of this request. Poll it at /v1/jobs/{request_id}. |
status | string | pending, complete or failed. Always check it, even on HTTP 200. |
credits | integer | Requests charged: 1 when complete, 0 while pending or when failed. |
cached | boolean | True when the result came from the 15-minute cache. |
poll_url | string | Only while pending. A path like /v1/jobs/{id}: join it to https://api.soldgraph.com, not to the /v1 base URL. |
error.code | string | Only when failed. See failed job codes. |
result | object | Only when complete. One source page from the marketplace. |
result.provider | string | Marketplace ID, like ebay or poshmark. |
result.country | string | Always us. |
result.query | string | The q you sent, with extra spaces removed. |
result.page | integer | The page you asked for. |
result.count | integer | Rows in result.data on this page. |
result.reported_total | integer | Total matches the marketplace reports for the search. It may be rounded or capped. |
result.next_page | integer | null | Send this as page to get the next page. Null on the last page. |
result.collected_at | string | When we collected the page, as an ISO 8601 timestamp. |
result.schema_version | integer | Version of this response shape. Currently 1. |
result.completeness | string | Always provider_page_only: one page, not a full sales history. |
result.field_notes | string | Plain-text notes on how to read this page's fields. |
result.page_size | integer | Rows per page, as eBay reports it. |
result.data[].id | string | The marketplace's listing ID. |
result.data[].title | string | null | Listing title as shown. |
result.data[].link | string | URL of the listing on the marketplace. |
result.data[].displayed_price | object | null | { amount, currency } parsed from the price shown. Null if it couldn't be read. Null when eBay shows a price range for a multi-variation listing ("$247.00 to $911.00"): the amount wouldn't say which variant. The range stays in displayed_price_text. |
result.data[].displayed_price_text | string | null | The price text as shown, like $189.00. |
result.data[].displayed_shipping | object | null | { amount, currency } read from exact shipping text, like +$9.99 delivery. Free delivery is 0. Estimates and Shipping not specified are null. |
result.data[].shipping_text | string | null | Shipping text as shown, like +$9.99 delivery or Free delivery. |
result.data[].sold_date | string | null | Sale date as YYYY-MM-DD. eBay's text has no year, so we use the most recent date that matches. |
result.data[].sold_date_text | string | null | Sold date text as shown, like Sep-21 14:35. eBay leaves out the year. |
result.data[].condition | string | null | eBay's condition text as shown, like Pre-Owned. |
result.data[].seller_text | string | null | Seller text as eBay shows it: username, feedback count and positive percentage, e.g. clutch_supply (1,325) 99.7%. |
result.data[].brand | null | Always null on eBay. |
result.data[].size | null | Always null on eBay. |
result.data[].image | string | null | Image URL on i.ebayimg.com. |
result.data[].price | null | Always null. Reserved for a verified sale price. |
result.data[].shipping | null | Always null. Reserved for a verified shipping amount. |
result.data[].sold_at | null | Always null. Reserved for a verified sale time. |
result.data[].took_offer | null | Always null. Reserved for whether a Best Offer was accepted. |
displayed_price is the price eBay shows. It can differ from what the buyer paid, for example after an accepted offer. Fields we can't verify are null.
sold_dateis the sale date asYYYY-MM-DD. eBay'ssold_date_texthas no year, so we use the most recent date that matches.displayed_shippingis read only from exact text like+$9.99 delivery.Free deliveryis 0. Estimates andShipping not specifiedare null.conditionis eBay's own text, likePre-Owned.brandandsizeare always null on eBay. They exist so rows have the same fields on every marketplace.
Try it