findCompletedItems Replacement: Migrating Off eBay's Finding API (With Field Mapping)

There is no open, official replacement. eBay decommissioned the Finding API, including findCompletedItems, on February 5, 2025. Its official sold-data successor, the Marketplace Insights API, is Limited Release and closed to most new developers, and the Browse API has no sold items. Most teams now swap findCompletedItems for a hosted sold-listings API that takes a keyword and returns completed sales as JSON.
Legacy findCompletedItems request marked decommissioned Feb 5, 2025, next to a replacement GET /v1/sold card returning 200 OK

If a cron job that's been running since 2015 suddenly started returning nothing, this is probably why. eBay's Finding API, and with it findCompletedItems, the call half the reseller tools on the internet were built on, is gone.

What happened to findCompletedItems

  • October 15, 2020: eBay staff confirmed findCompletedItems was deprecated and access restricted. New apps couldn't call it; old ones limped along.
  • January 2024: eBay announced the Finding and Shopping APIs would be decommissioned.
  • February 5, 2025: decommissioned. The endpoint no longer serves requests.

eBay's official migration path is the Browse API, which is fine if you were using Finding for active listings. For sold items, there's no drop-in successor you can sign up for. A developer on eBay's forums looked for one and concluded: "The only comparable api is" Marketplace Insights, and that one is Limited Release.

Side by side code: the old findCompletedItems request URL with SoldItemsOnly filter, and the replacement single GET request in Python
Same job, about a third of the code, and no XML.

Field-by-field mapping

The Finding API returned XML (or JSON-wrapped XML) where every value was an array. Here's where each field you probably used lives in a SaleHistory /v1/sold response.

findCompletedItems fieldSaleHistory fieldNotes
itemIditem_idSame eBay item number
titletitle
sellingStatus.currentPricesold_price.valueFinal sold price
sellingStatus.currentPrice@currencyIdsold_price.currency
sellingStatus.sellingState = EndedWithSales(implicit)Every item returned sold
listingInfo.endTimesold_atISO date
listingInfo.listingTypebuying_formatauction or fixed_price
listingInfo.bestOfferEnabledbest_offer_acceptedTrue only when an offer was actually accepted
shippingInfo.shippingServiceCostshipping.value0 for free shipping
condition.conditionDisplayNamecondition
viewItemURLurl
paginationOutput.totalEntriescountUp to 200 per request, no paging

Two things you no longer have to write yourself: a stats block (median, p25/p75, min, max) and a flags array that marks lots, for-parts listings and outliers. Seller details aren't in the response: they don't help you price an item, so we left them out.

The request, translated

Old:

GET https://svcs.ebay.com/services/search/FindingService/v1
  ?OPERATION-NAME=findCompletedItems
  &SERVICE-VERSION=1.13.0
  &SECURITY-APPNAME=YourAppID
  &RESPONSE-DATA-FORMAT=JSON
  &keywords=nintendo%2064%20console
  &itemFilter(0).name=SoldItemsOnly&itemFilter(0).value=true
  &itemFilter(1).name=Condition&itemFilter(1).value=3000
  &paginationInput.entriesPerPage=100

New:

GET https://api.soldcomps.io/v1/sold?q=nintendo+64+console&condition=used
Authorization: Bearer sh_live_xxxxxxxx
Finding itemFilterSaleHistory param
SoldItemsOnly=true(default, always sold)
Condition=1000 / 3000 / 7000condition=new / used / for_parts
MinPrice / MaxPricemin_price / max_price
ListingType=Auctionbuying_format=auction
categoryId(none; put category words in q)
GLOBAL-ID=EBAY-GBsite=EBAY_GB

A drop-in shim

If you have a lot of code that expects the old response shape, wrap the new call and keep your callers unchanged:

import requests

def find_completed_items(keywords, condition=None, key=None):
    """Returns a list shaped like the old Finding API searchResult.item array."""
    r = requests.get(
        "https://api.soldcomps.io/v1/sold",
        params={"q": keywords, **({"condition": condition} if condition else {})},
        headers={"Authorization": f"Bearer {key}"},
        timeout=30,
    )
    r.raise_for_status()
    return [
        {
            "itemId": [it["item_id"]],
            "title": [it["title"]],
            "sellingStatus": [{
                "currentPrice": [{"__value__": str(it["sold_price"]["value"]),
                                  "@currencyId": it["sold_price"]["currency"]}],
                "sellingState": ["EndedWithSales"],
            }],
            "listingInfo": [{"endTime": [it["sold_at"]]}],
            "viewItemURL": [it["url"]],
        }
        for it in r.json()["items"]
    ]

Once everything's migrated, delete the shim and read the clean fields directly. The Python tutorial shows the idiomatic version.

Things that behave differently

  • No pagination. One request returns up to 200 sales. That's the whole 90-day picture for most specific queries. If you need more, narrow the query (add condition, a price band or more specific keywords) rather than paging.
  • 90 days, not forever. eBay only exposes about 90 days of completed sales publicly. That was true of findCompletedItems too.
  • Best Offer. eBay sometimes hides the accepted offer amount. Those rows have best_offer_price_known: false and are kept out of stats. Read how Best Offer inflates comps.
  • No eBay credentials. findCompletedItems needed your AppID. Now you only send your SaleHistory key. That matters more since eBay started requiring sign-in for sold search.

Frequently asked questions

When was findCompletedItems shut down?

eBay restricted findCompletedItems in October 2020, deprecated the Finding API in January 2024, and decommissioned it on February 5, 2025.

What error does findCompletedItems return now?

Calls to the Finding API endpoint fail because the service is decommissioned. Before the shutdown, restricted apps typically saw errorId 10001 or an access error for the call.

Is the Browse API a replacement for findCompletedItems?

Only for active listings. eBay named Browse as the Finding API's successor, but it returns items currently for sale, never sold or completed items.

Does the replacement return auctions and Best Offer sales?

Yes. Each item has buying_format (auction or fixed_price) and a best_offer_accepted flag. When eBay hides the accepted offer amount, best_offer_price_known is false and the item is left out of the median.

Sources

  1. eBay Community: findCompletedItems does not work (eBay staff: deprecated Oct 15, 2020) (accessed Oct 22, 2026)
  2. eBay Community: Alert: Finding API and Shopping API to be decommissioned in 2025 (accessed Oct 22, 2026)
  3. eBay Community: findCompletedItems replacement (accessed Oct 22, 2026)
  4. Stack Overflow: eBay API findCompletedItems replacement/work-around (accessed Oct 22, 2026)

SaleHistory sells an eBay sold-listings API, so we have a commercial interest in this topic. We link primary sources so you can check our work. Spotted something out of date? Email hello@soldcomps.io.