> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scrapebadger.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Completed / Sold Listings

> Search eBay completed (sold) listings — the closing prices buyers actually paid.

The completed-listings endpoint returns **sold** items — the closing prices buyers
actually paid, with the date each item sold. Every result has `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

<ParamField query="query" type="string" required>
  Search keywords. Matches against listing titles.
</ParamField>

<ParamField query="domain" type="string" default="com">
  eBay marketplace domain TLD or alias. See [`/v1/ebay/markets`](/api-reference/endpoint/ebay/list-markets) for all supported values.

  Examples: `com`, `co.uk`, `de`, `fr`, `com.au`
</ParamField>

<ParamField query="category_id" type="string">
  Restrict results to an eBay category id. Use [`/v1/ebay/categories`](/api-reference/endpoint/ebay/list-categories) to look up ids.
</ParamField>

<ParamField query="page" type="integer" default={1}>
  Page number for paginated results. Range: `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.
</ParamField>

<ParamField query="per_page" type="integer">
  Results per page. Clamped to one of `60`, `120`, or `240`.
</ParamField>

<ParamField query="sort_by" type="string" default="best_match">
  Sort order for results.

  | 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 |
</ParamField>

<ParamField query="condition" type="string">
  Item condition filter (`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.
</ParamField>

<ParamField query="location" type="string">
  Item location.

  | Value | Description |
  | - | - |
  | `domestic` | Only items located in this marketplace's own country (`domain=fr` → France only) |
  | `worldwide` | Items from every country |

  Omit it and you get eBay's default, which mixes foreign listings into a national
  marketplace. Two things follow from that, and both matter for price research:
  a national price series picks up sales that never happened in that country, and
  a foreign listing's price is shown **converted** into the marketplace's currency
  rather than the amount it actually sold for. `location=domestic` removes both.
</ParamField>

<ParamField query="min_price" type="number">
  Minimum sold-price filter in the marketplace's local currency.
</ParamField>

<ParamField query="max_price" type="number">
  Maximum sold-price filter in the marketplace's local currency.
</ParamField>

## Response

Identical shape to [`/v1/ebay/search`](/api-reference/endpoint/ebay/search), except `sold` is `true`, each result's `price` reflects the **final sold price**, and each result carries a `sold_date`.

<ResponseField name="query" type="string">The search query that was executed.</ResponseField>
<ResponseField name="domain" type="string">Marketplace domain that was searched.</ResponseField>
<ResponseField name="sold" type="boolean">Always `true` for completed/sold listings.</ResponseField>

<ResponseField name="results" type="array">
  Array of sold listings (same `SearchResult` shape as active search).

  <Expandable title="SearchResult object">
    <ResponseField name="position" type="integer">Position on the page (1-based).</ResponseField>
    <ResponseField name="item_id" type="string">eBay listing item id.</ResponseField>
    <ResponseField name="title" type="string">Listing title.</ResponseField>
    <ResponseField name="url" type="string">Full URL to the listing.</ResponseField>
    <ResponseField name="image" type="string">Primary image URL.</ResponseField>
    <ResponseField name="price" type="object">Final **sold** price with `value`, `currency`, `symbol`, `raw`.</ResponseField>
    <ResponseField name="condition" type="string">Item condition label.</ResponseField>
    <ResponseField name="buying_format" type="string">`Buy It Now`, `Auction`, or `Best Offer`.</ResponseField>
    <ResponseField name="is_auction" type="boolean">Whether the listing was an auction.</ResponseField>
    <ResponseField name="bids" type="integer">Number of bids the auction received (nullable).</ResponseField>
    <ResponseField name="current_bid" type="object">Winning bid for auction listings with `value`, `currency`, `symbol`, `raw`; mirrors `price`. Null for fixed-price listings.</ResponseField>
    <ResponseField name="shipping" type="string">Shipping text.</ResponseField>
    <ResponseField name="location" type="string">Item location text.</ResponseField>
    <ResponseField name="sold_date" type="string">Sale date text as rendered by eBay, e.g. `Aug 19, 2026`. Localized on non-English marketplaces (e.g. `Verkauft 5. Okt. 2024`), nullable.</ResponseField>
    <ResponseField name="sold_date_at" type="string">Best-effort ISO date parsed from `sold_date`, e.g. `2026-08-19`. Null when the marketplace's date format is not English.</ResponseField>
    <ResponseField name="seller_name" type="string">Seller username (nullable).</ResponseField>
    <ResponseField name="is_sponsored" type="boolean">Always `null`. eBay renders its "Sponsored" badge into every card as anti-scraping bait, so promoted placements cannot be distinguished from organic results.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="facets" type="object">Available filter facets keyed by name.</ResponseField>

<ResponseField name="pagination" type="object">
  Pagination metadata with `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.
</ResponseField>

<ResponseField name="scraped_at" type="string">ISO 8601 timestamp when the results were scraped.</ResponseField>

### Example Response

```json theme={null}
{
  "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`:

```python theme={null}
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
```

<Warning>
  Do not loop on "until the response is empty" alone. Past its last page eBay
  **clamps** — asking for page 200 of a 133-page result set re-serves page 133.
  This API detects that and returns an empty page with `has_more: false`, but a
  client that ignores `has_more` and retries forever will keep spending credits.
</Warning>

A broad sold search runs roughly 130 pages deep at `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.

<Note>
  Each completed/sold request costs **5 credits**. Failed requests are not charged.
</Note>


## OpenAPI

````yaml GET /v1/ebay/completed
openapi: 3.1.0
info:
  title: ScrapeBadger eBay API
  version: 1.0.0
  description: >-
    eBay marketplace scraping API for searching active and completed (sold)
    listings, fetching item details, reviews, sellers, seller listings and
    feedback, category browsing, autocomplete, and reference data across 18
    marketplaces.
servers:
  - url: https://scrapebadger.com
    description: Production
security:
  - apiKeyAuth: []
paths:
  /v1/ebay/completed:
    get:
      tags:
        - eBay Search
      summary: Completed / Sold Listings
      description: >-
        Search eBay completed (sold) listings — the closing prices buyers
        actually paid, with the date each item sold. `sold` is `true` on the
        envelope and each result's `price` is the final sold price. Served via
        an authenticated eBay session. Costs 5 credits; failed requests are
        free.
      operationId: searchEbayCompleted
      parameters:
        - name: query
          in: query
          required: true
          schema:
            type: string
          description: Search keywords.
        - name: domain
          in: query
          schema:
            type: string
            default: com
          description: eBay marketplace domain TLD or alias (com, co.uk, de, fr, ...).
        - name: category_id
          in: query
          schema:
            type: string
          description: Restrict results to a category id.
        - name: page
          in: query
          schema:
            type: integer
            default: 1
            minimum: 1
            maximum: 1000
          description: Page number for paginated results.
        - name: per_page
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 240
          description: Results per page. Clamped to 60, 120 or 240.
        - name: sort_by
          in: query
          schema:
            type: string
            default: best_match
            enum:
              - best_match
              - ending_soonest
              - newly_listed
              - price_low_to_high
              - price_high_to_low
          description: Sort order for results.
        - name: condition
          in: query
          schema:
            type: string
            enum:
              - new
              - open_box
              - refurbished
              - used
              - for_parts
              - graded
              - ungraded
          description: >-
            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.
        - name: min_price
          in: query
          schema:
            type: number
            minimum: 0
          description: Minimum price filter in the marketplace's local currency.
        - name: max_price
          in: query
          schema:
            type: number
            minimum: 0
          description: Maximum price filter in the marketplace's local currency.
        - name: location
          in: query
          required: false
          description: >-
            Item 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.
          schema:
            type: string
            enum:
              - domestic
              - worldwide
      responses:
        '200':
          description: Completed / sold listings
          content:
            application/json:
              schema:
                type: object
                properties:
                  query:
                    type:
                      - string
                      - 'null'
                  domain:
                    type: string
                  category_id:
                    type:
                      - string
                      - 'null'
                  sold:
                    type: boolean
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        position:
                          type: integer
                        item_id:
                          type:
                            - string
                            - 'null'
                        product_id:
                          type:
                            - string
                            - 'null'
                        title:
                          type:
                            - string
                            - 'null'
                        url:
                          type:
                            - string
                            - 'null'
                        image:
                          type:
                            - string
                            - 'null'
                        price:
                          type: object
                          properties:
                            value:
                              type:
                                - number
                                - 'null'
                            currency:
                              type:
                                - string
                                - 'null'
                            symbol:
                              type:
                                - string
                                - 'null'
                            raw:
                              type:
                                - string
                                - 'null'
                        original_price:
                          type: object
                          properties:
                            value:
                              type:
                                - number
                                - 'null'
                            currency:
                              type:
                                - string
                                - 'null'
                            symbol:
                              type:
                                - string
                                - 'null'
                            raw:
                              type:
                                - string
                                - 'null'
                        discount_percent:
                          type:
                            - number
                            - 'null'
                        currency:
                          type:
                            - string
                            - 'null'
                        condition:
                          type:
                            - string
                            - 'null'
                        brand:
                          type:
                            - string
                            - 'null'
                        buying_format:
                          type:
                            - string
                            - 'null'
                        is_auction:
                          type: boolean
                        bids:
                          type:
                            - integer
                            - 'null'
                        time_left:
                          type:
                            - string
                            - 'null'
                        current_bid:
                          type:
                            - object
                            - 'null'
                          description: >-
                            Current high bid for auction listings; mirrors
                            `price`. Null for non-auction (fixed-price)
                            listings.
                          properties:
                            value:
                              type:
                                - number
                                - 'null'
                            currency:
                              type:
                                - string
                                - 'null'
                            symbol:
                              type:
                                - string
                                - 'null'
                            raw:
                              type:
                                - string
                                - 'null'
                        shipping:
                          type:
                            - string
                            - 'null'
                        shipping_cost:
                          type: object
                          properties:
                            value:
                              type:
                                - number
                                - 'null'
                            currency:
                              type:
                                - string
                                - 'null'
                            symbol:
                              type:
                                - string
                                - 'null'
                            raw:
                              type:
                                - string
                                - 'null'
                        free_shipping:
                          type:
                            - boolean
                            - 'null'
                        location:
                          type:
                            - string
                            - 'null'
                        returns:
                          type:
                            - string
                            - 'null'
                        sold_count:
                          type:
                            - integer
                            - 'null'
                        sold_date:
                          type:
                            - string
                            - 'null'
                          description: >-
                            Sale date text as rendered by eBay on the sold card,
                            e.g. "2 Jul 2026". Localized on non-English
                            marketplaces (e.g. "Verkauft 5. Okt. 2024"). Null on
                            active listings.
                          examples:
                            - 2 Jul 2026
                        sold_date_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            Best-effort ISO 8601 date parsed from sold_date,
                            e.g. "2026-07-02". Null when the marketplace's date
                            format is not English.
                          examples:
                            - '2026-07-02'
                        watchers:
                          type:
                            - integer
                            - 'null'
                        coupon:
                          type:
                            - string
                            - 'null'
                        rating:
                          type:
                            - number
                            - 'null'
                        ratings_total:
                          type:
                            - integer
                            - 'null'
                        seller_name:
                          type:
                            - string
                            - 'null'
                        seller_feedback_percent:
                          type:
                            - number
                            - 'null'
                        seller_feedback_score:
                          type:
                            - integer
                            - 'null'
                        program_badge:
                          type:
                            - string
                            - 'null'
                        is_sponsored:
                          type:
                            - boolean
                            - 'null'
                          description: >-
                            Always null — eBay renders its Sponsored badge into
                            every card as anti-scraping bait, so promoted
                            placements cannot be distinguished from organic
                            results.
                  facets:
                    type: object
                    additionalProperties:
                      type: array
                      items:
                        type: string
                  pagination:
                    type: object
                    properties:
                      current_page:
                        type: integer
                      per_page:
                        type:
                          - integer
                          - 'null'
                      total_pages:
                        type:
                          - integer
                          - 'null'
                      total_results:
                        type:
                          - integer
                          - 'null'
                      has_more:
                        type:
                          - boolean
                          - 'null'
                        description: >-
                          True while eBay still offers a next page — the stop
                          signal for bulk extraction. total_results is populated
                          on completed/sold; total_pages may be null. Past the
                          last page eBay re-serves it, so page on has_more
                          rather than looping until empty.
                  scraped_utc:
                    type:
                      - number
                      - 'null'
                  scraped_at:
                    type:
                      - string
                      - 'null'
components:
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.