Grail

Migration guide

FindCompletedItems alternative

FindCompletedItems was the legacy eBay call developers used to pull ended listings. It is deprecated and retired. Grail covers the same job with one JSON request — up to 240 real eBay sold listings, no App ID, no XML, no paging.

Background

What FindCompletedItems was

FindCompletedItems was part of eBay’s legacy Finding API — a public, XML-based service for searching listings that had already ended. It was the common first stop for anyone building sold-price history, because for a long time it was the only public way to ask eBay “what has this item actually sold for?”.

It came with hard edges. Results were limited to roughly the last 90 days, returned only 100 records per page, and the price it reported was the listing’s price — not a confirmed final sale price, and it mixed in items that ended without selling. You needed an eBay developer App ID and had to manage call volume yourself.

eBay deprecated the Finding API and decommissioned the family that included FindCompletedItems in early 2025. Existing integrations stopped returning data; new keys could no longer call it. The service is retired.

Why it is hard now

The friction, up front

  • —Retired: eBay deprecated the Finding API and decommissioned FindCompletedItems in early 2025 — the call is no longer served.
  • —~90-day window: completed listings were only searchable for roughly the last 90 days.
  • —100 rows per page: building any real volume meant paging manually through a rate-limited endpoint.
  • —Price ≠ final sale: it returned the listing price, not a confirmed final sold price, and included items that ended without selling.
  • —XML + App ID: responses were XML and required an eBay developer App ID plus your own call-rate management.

The replacement

How Grail replaces it

Grail is a single JSON endpoint that does the job FindCompletedItems used to do, without the retired call. Send a keyword, get back up to 240 real eBay sold listings from the same roughly-90-day window — each row carrying the final sold price, sale date, condition, seller, shipping, item location, and a link back to the source listing.

There is no App ID, no XML envelope, and no manual paging for a normal request: one call returns a full page of sold comps plus a summary (median, mean, min, max, p25, p75). Add relevance=true when you want the median computed after accessories, parts, and wrong-model matches are stripped out — cleaning is opt-in, so you keep the raw feed by default.

Up to 240 rows per call

One request returns up to 240 real eBay sold listings — more than a legacy page, in JSON instead of XML.

~90 days of history

The same recent sold window the legacy call covered, served fresh with provenance on every row.

Cleaned median, opt-in

Pass relevance=true to compute the median after accessories, parts, and wrong models are removed.

36 fields per row

Sold price, date, condition, seller, shipping, location, source URL and more — structured, not scraped HTML.

REST + MCP

Call it over HTTP from any language, or wire it into an AI agent through the hosted MCP connector.

Free to start

100 requests a month free, no card. Mint a key and make your first call in under a minute.

Code

Make the call

curl

curl -H "Authorization: Bearer $GRAIL_KEY" \
  "https://grail.solutions/v1/scrape?keyword=iphone+13+pro&count=240&sold=true&relevance=true"

Python

import requests

KEY = "grail_..."  # free key: https://grail.solutions/signup

r = requests.get(
    "https://grail.solutions/v1/scrape",
    params={"keyword": "iphone 13 pro", "count": 240, "sold": "true", "relevance": "true"},
    headers={"Authorization": f"Bearer {KEY}"},
)
data = r.json()

print(data["rawMedian"])          # summary over the sold set
print(len(data["items"]))         # up to 240 real sold listings
print(data["items"][0]["soldPrice"])

Note: prices come back as decimal strings (e.g. "499.00") — cast to float before doing math. Get a key at /signup — 100 requests a month free, no card — then mint it at /dashboard/api-keys.

FAQ

What replaced eBay’s FindCompletedItems call?

eBay retired the Finding API that FindCompletedItems belonged to in early 2025. Grail replaces the job with one JSON request to GET /v1/scrape that returns up to 240 real eBay sold listings from the recent sold window.

Do I need an eBay App ID or developer account?

No. Grail issues its own API key from a free account — 100 requests a month, no card. There is no eBay App ID, OAuth, or approval step.

How is this different from the old XML response?

Every Grail response is JSON. Each row carries 36 fields including the final sold price, sale date, condition, shipping, item location, and a link to the source listing, plus a median/range summary you can use immediately.

Can I get the median with accessories and wrong models removed?

Yes — cleaning is opt-in. Pass relevance=true and the median is computed after accessories, parts, and wrong-model matches are stripped out. Leave it off for the raw eBay feed.

More guides & starting points

Start free — 100 requests a month.

No credit card. Your own key in the dashboard in under a minute.

Create free account