CompSniper Docs

eBay Image Search API (Sold Prices From a Photo)

Send a photo and get eBay sold listings for that item. POST /v1/scrape/image identifies the product, shows the keyword it used, and runs the full sold search. 2 requests per success, nothing when the photo cannot be identified.

Price an item from a photo. POST /v1/scrape/image reads the photo, identifies the product (brand, model, variant, and for trading cards the set, card number, grader and grade), turns it into an eBay search keyword, and runs the normal sold search with it. The response shows exactly what we identified and searched for, followed by up to 240 sold listings and the price summary.

  • 2 requests per successful search: 1 to read the photo, 1 for the sold search.
  • Nothing charged when the photo cannot be identified (422 image_not_identified) or the search fails.
  • Every sold search option works: ebaySite, count, itemCondition, bestOfferPrice, sellerCountry, postalCode and the rest, passed in the query string.
  • You see the keyword. If the photo is read wrong, search again with GET /v1/scrape and your own keyword.

Make a request

Upload the photo as the multipart field image:

curl --fail-with-body \
  -H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
  -F "[email protected]" \
  "https://api.compsniper.com/v1/scrape/image?count=60"

Or pass a public image link:

curl --fail-with-body \
  -H "Authorization: Bearer cs_live_REPLACEWITHYOURKEY" \
  -H "Content-Type: application/json" \
  -d '{"imageUrl": "https://example.com/photos/charizard-psa10.jpg"}' \
  "https://api.compsniper.com/v1/scrape/image?count=60&bestOfferPrice=true"
Python
import requests

with open("sneaker.jpg", "rb") as photo:
    response = requests.post(
        "https://api.compsniper.com/v1/scrape/image",
        headers={"Authorization": "Bearer cs_live_REPLACEWITHYOURKEY"},
        params={"count": 60},
        files={"image": ("sneaker.jpg", photo, "image/jpeg")},
        timeout=120,
    )
if response.status_code == 422:
    print(response.json()["error"])  # not identified, not charged
else:
    response.raise_for_status()
    data = response.json()
    print("Searched for:", data["identified"]["keyword"], data["identified"]["confidence"])
    print("Median sold price:", data["summary"]["median"], "from", data["summary"]["count"], "sales")
Node.js
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("image", new Blob([await readFile("watch.jpg")], { type: "image/jpeg" }), "watch.jpg");
const res = await fetch("https://api.compsniper.com/v1/scrape/image?count=60", {
  method: "POST",
  headers: { Authorization: "Bearer cs_live_REPLACEWITHYOURKEY" },
  body: form,
});
const data = await res.json();
console.log(data.identified?.keyword, data.summary?.median);

Ways to send the photo

HowRequest
File uploadmultipart/form-data with the field image
Raw image bodyContent-Type: image/jpeg (or image/png, image/webp, image/gif, image/heic) with the bytes as the body
Public linkJSON body {"imageUrl": "https://..."}, or ?imageUrl= in the query string

Images up to 8 MB. Links must be public https:// addresses.

Example response

The identified block comes first, then the same fields as GET /v1/scrape.

{
  "identified": {
    "keyword": "LEGO Star Wars Millennium Falcon 75192",
    "confidence": 1,
    "category": "toy",
    "details": { "brand": "LEGO", "model": "Millennium Falcon", "set": "75192" }
  },
  "requestsCharged": 2,
  "keyword": "LEGO Star Wars Millennium Falcon 75192",
  "page": 1,
  "hasNextPage": true,
  "summary": { "count": 60, "currency": "USD", "median": 949.99, "mean": 921.43, "min": 700, "max": 1099, "p25": 908.15, "p75": 949.99 },
  "items": [ "... sold listings, the same fields as /v1/scrape ..." ]
}
FieldDescription
identified.keywordThe eBay search we ran.
identified.confidence0 to 1. Photos below 0.6 are refused rather than guessed.
identified.categorytrading_card, sneakers, electronics, clothing, toy, watch, collectible, media or other.
identified.detailsWhat was read from the photo: brand, model, variant, color, size, year, set, cardNumber, player, grader, grade (only the ones found).
requestsCharged2 on success.

Tips for photos that identify well

  • Show the label, the box front, the model number or the card front. For graded cards, include the slab label.
  • One item per photo, filling most of the frame.
  • If the model or generation cannot be told from the outside (for example the storage size of a phone), the photo is refused rather than guessed. Search with GET /v1/scrape and the exact model instead.

Errors

SituationStatusCharged
Photo identified and sold search returned2002 requests
Photo does not show one identifiable item, or confidence below 0.6422 image_not_identifiedno
Image link unreachable or not an image422 image_unavailable / invalid_imageno
Image larger than 8 MB413 invalid_imageno
More than 20 photos in a minute429 rate_limitedno
Not enough requests left for both steps429 quota_exceededno
Sold search failed after identificationthe search error, with identified includedno

On this page