Blog / API guides

eBay API: Search Results, Items and Autocomplete as JSON

The eBay API here returns eBay search results as JSON with one GET request to /v1/ebay/search, authenticated with an X-API-Key header. Your key is the only credential you need. The same API has an item endpoint and an autocomplete endpoint. Each successful call costs 1 credit, and failed calls cost nothing.

How do you get eBay search results as JSON?

Send a GET request to https://api.perceptlayer.com/v1/ebay/search with a query in q and your key in the X-API-Key header. The response is JSON with a results array, one object per listing, so there's no HTML to parse. Here is the request we recorded a response for:

curl "https://api.perceptlayer.com/v1/ebay/search?q=coffee+maker&page=1&per_page=60" \
  -H "X-API-Key: $API_KEY"

To get a key, sign up for a free API key. Keys start with sk_live_, and the authentication docs cover the header and the api_key query parameter for places where you can't set headers.

If you'd rather try it before writing code, the eBay API page has a playground. Pick an endpoint, fill in the parameters and run a real call with your key.

Which parameters does the search endpoint take?

The search endpoint has one required parameter, q, and twelve optional ones for category, paging, sorting and filtering. Only q, per_page, sort and location_postal carry documented limits or allowed values. Boolean filters like free_shipping take true or false. The full list is on the eBay Search endpoint page.

Parameter Type Required Notes
q string yes Up to 255 characters
category integer no A category ID
page integer no Page number
per_page integer no One of 60, 120, 240
sort integer no One of 1, 7, 10, 12, 15, 16
buy_it_now boolean no Filter for Buy It Now listings
auction boolean no Filter for auction listings
condition[] list of integer no One or more condition IDs
price_min number no Lower price bound
price_max number no Upper price bound
free_shipping boolean no Filter for free shipping
preferred_location integer no Location ID
location_postal string no Up to 20 characters

The values for sort, category, condition[] and preferred_location are numeric IDs. The catalogue doesn't document what each ID means, so don't guess. Run the playground with a value, look at the order or the listings that come back, and note what you find.

Filters combine in one request. This one asks for 120 results per page, priced between 20 and 80, with free shipping:

curl -G "https://api.perceptlayer.com/v1/ebay/search" \
  --data-urlencode "q=coffee maker" \
  --data-urlencode "per_page=120" \
  --data-urlencode "price_min=20" \
  --data-urlencode "price_max=80" \
  --data-urlencode "free_shipping=true" \
  -H "X-API-Key: $API_KEY"

What does a search response look like?

A search response wraps everything in success and data. Inside data you get the echoed query, page and per_page, a has_more flag, the results array, total_results, related_searches and categories. This is an excerpt of the real response to the coffee maker request above, trimmed with …:

{
  "success": true,
  "data": {
    "query": "coffee maker",
    "page": 1,
    "per_page": 60,
    "has_more": true,
    "results": [
      {
        "product_id": "366702966104",
        "title": "Mr. Coffee 4-in-1 Single-Serve Latte, Iced, and Hot Coffee",
        "link": "https://www.ebay.com/itm/366702966104",
        "price": {
          "raw": "$60.00",
          "extracted": 60,
          "currency": "USD"
        },
        "sponsored": true,
        "subtitle": "Brand New",
        "thumbnail": "https://i.ebayimg.com/images/g/fhEAAeSwuP5qvcJe/s-l500.webp",
        "location": "United States"
      },
      {
        "product_id": "167322718667",
        "title": "New Keurig Green Mountain K4000 Cafe System Commercial K-Cup Coffee Maker",
        "link": "https://www.ebay.com/itm/167322718667",
        "price": {
          "raw": "$428.98",
          "extracted": 428.98,
          "currency": "USD"
        },
        "sponsored": true,
        "subtitle": "Brand New",
        "thumbnail": "https://i.ebayimg.com/images/g/UVIAAOSwdnFnmqXS/s-l500.webp",
        "location": "United States"
      },
      …
    ],
    "total_results": 110000,
    "related_searches": [
      {
        "query": "keurig coffee maker",
        "link": "https://www.ebay.com/sch/i.html?_nkw=keurig+coffee+maker&_sop=12"
      },
      …
    ],
    "categories": [
      {
        "id": 11700,
        "name": "Home & Garden"
      },
      …
    ]
  }
}

Fields worth knowing

Prices come as an object: raw is the display string, extracted is a number you can sort on, and currency is the code. That saves you from stripping a dollar sign. In the excerpt, the first result's extracted is 60 and the second's is 428.98, so it's a plain number whether or not there are cents. The sponsored flag lets you drop or separate promoted listings.

Field What it holds
product_id The listing's ID
title, subtitle Listing title and the condition line, such as "Brand New"
link, thumbnail Listing URL and image URL
price.extracted Numeric price
sponsored Whether the listing is promoted
location A location string, such as "United States"

How do you page through results?

Paging uses page and per_page, and has_more in the response tells you when to stop. Request page 1, process results, then increment page while has_more is true. Each page is one call at 1 credit, whatever per_page you pick, so a crawl's cost is the number of pages you request, and you can cap it in your own loop.

import os
import requests

URL = "https://api.perceptlayer.com/v1/ebay/search"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}

page, listings = 1, []
while page <= 3:
    r = requests.get(
        URL,
        headers=HEADERS,
        params={"q": "coffee maker", "page": page, "per_page": 120},
        timeout=30,
    )
    r.raise_for_status()
    data = r.json()["data"]
    listings.extend(data["results"])
    if not data["has_more"]:
        break
    page += 1

print(len(listings), "listings")

The loop stops after three pages as a guard. Remove the cap once you know what a full crawl costs. Three pages is 3 credits, however many listings each page holds.

How do you fetch a single item?

Call GET /v1/ebay/item with item_id, its only parameter and a required string of up to 20 characters, to look up one listing. In the recorded search response, product_id is the same number as the listing's /itm/ link, so the example below passes it as item_id; confirm in the playground that the IDs line up for your listings. The call costs 1 credit, and the response headers X-Credits-Used and X-Credits-Remaining show what it cost and what's left. You can try it in the playground first. The eBay Item endpoint page has the details.

curl "https://api.perceptlayer.com/v1/ebay/item?item_id=366702966104" \
  -H "X-API-Key: $API_KEY"

We haven't recorded an item or autocomplete response for this article, so we won't show one. Run the calls in the playground to see what they return before you build against them.

What does the autocomplete endpoint do?

GET /v1/ebay/autocomplete is for query suggestions as a user types. Its only parameter is q, a required string of up to 255 characters, such as a partial search term. It costs 1 credit per successful call, so a suggestion lookup per keystroke adds up quickly; a failed call returns X-Credits-Used: 0. The playground on the eBay API page lets you see what comes back. The eBay Autocomplete endpoint page has the details.

curl "https://api.perceptlayer.com/v1/ebay/autocomplete?q=coffee+mak" \
  -H "X-API-Key: $API_KEY"

What does each call cost?

Every eBay endpoint costs 1 credit per successful call. A failed call costs nothing and returns X-Credits-Used: 0. Successful responses carry X-Credits-Used and X-Credits-Remaining, so you can watch your balance without a separate request. The credits docs explain the accounting.

Pack Credits eBay calls at 1 credit
Free 1,000 a month 1,000
Starter 10,000 10,000
Build 50,000 50,000
Growth 200,000 200,000

Here is a worked example. Say you track 500 keywords daily with one search call each, 20 days a month: 500 × 20 = 10,000 calls × 1 credit = 10,000 credits. That is exactly one Starter pack of 10,000 credits, so a month with a few retries or extra item lookups would need a larger pack or the free credits on top. Purchased credits last 12 months, and there's no subscription. The service is prepaid, so when the balance runs out, calls return insufficient_credits (402) and nothing more is debited. See pricing for the current packs.

When should you look at eBay's own API?

Perceptlayer's eBay endpoints are read-only: search, item and autocomplete. Use eBay's own API when you need to write to eBay or build on eBay's own program terms. That means creating or managing listings, or relying on eBay's own search features. Two cases are concrete.

First, selling. eBay's Sell APIs are for building selling applications: configuring account settings, listing inventory, marketing listings and reporting on seller performance. Nothing in a read-only search endpoint does that, so if your product publishes or edits listings, go to eBay.

Second, buying features built on eBay's own platform. eBay's Browse API lets you search by keyword, category, image, product ID (EPID) or GTIN, and retrieve item details such as return policy terms and product review data. Our search endpoint takes keyword, category and filter parameters only, so image search or GTIN lookups are a reason to use eBay's. So is any need for an agreement directly with eBay.

This API fits when you want listings as JSON today, with one key and one header, and you want the same key to cover other sites. Data is collected from publicly available sources and returned as found at the time of the call, so check the output against your own needs before you depend on it.

Can an AI agent call these endpoints?

Yes. The MCP server at https://api.perceptlayer.com/mcp exposes search_endpoints, get_endpoint and call_endpoint. The first two only look up the catalogue and cost nothing; call_endpoint spends the endpoint's credits on success only. An agent can find the eBay search endpoint, read its parameters and call it. The MCP docs show the setup.

For wiring an agent end to end, see Claude MCP Web Search: Live Results for an Agent. To keep spend predictable once an agent is looping over searches, read AI Agent API Cost Control: Cap Web Data Spend.

What should you build first?

Start with one search in the playground, then copy the cURL call and swap in your own q. Once the fields look right, add price_min, price_max and free_shipping, and loop over page while has_more is true. Add the item endpoint for listings you want to look at individually.

Other marketplace and listing guides follow the same pattern: Zillow Listings API: Get Property Data as JSON and Airbnb Listings Data API: Search, Details and Reviews. The Marketplaces APIs page lists the rest of the area, and the API guides category collects the step-by-step posts. Get a free API key and run your first eBay search.

APIs in this post

Frequently asked questions

How much does an eBay search API call cost?

Each successful call to /v1/ebay/search, /v1/ebay/item or /v1/ebay/autocomplete costs 1 credit. The free tier gives 1,000 credits a month after you verify an email. Paid packs start at 10,000 credits, which is 10,000 eBay calls; see pricing for what credits cost. Failed calls cost nothing.

What happens when a request fails?

You get an HTTP status and a JSON body with error.code, error.message and error.request_id. Codes include invalid_api_key (401), insufficient_credits (402), invalid_parameters (422), rate_limited (429) and source_error (502). Failed calls return X-Credits-Used: 0. See the errors docs for the full list.

Can I search by category, price and condition?

Yes. /v1/ebay/search accepts category as an integer, price_min and price_max as numbers, and condition[] as a list of integers. It also takes buy_it_now, auction and free_shipping as booleans. The catalogue doesn't document what each category or condition ID means, so test values in the playground first.

How many results does one call return?

Set per_page to 60, 120 or 240 and use page to move through the results. The response includes total_results and a has_more flag. Each page is one call at 1 credit. The recorded example returned total_results: 110000 for "coffee maker".

Are there rate limits?

Yes. Limits are per account, shared by all its keys, and counted per minute. Free accounts get 1 request a second; paying accounts get at least 5 a second. A request over the limit returns rate_limited (429) and, like any failed call, isn't charged. Both 429 and 503 responses carry a Retry-After header with the seconds to wait. The rate limits docs describe how they work, and the requests docs cover the call format. Space out a large crawl and retry after a 429 instead of resending in a tight loop.

Is this the official eBay API, or an eBay scraper?

Neither. eBay runs its own developer program, and its APIs need a registered application and OAuth access tokens. A scraper is code you write and maintain against eBay's pages. This eBay API returns public search results, items and autocomplete as named JSON fields with one key, at 1 credit per successful call. Use eBay's own APIs when you sell on eBay or need account data.

  1. DuckDuckGo Search API: Web Results as JSON

    DuckDuckGo's Instant Answer API returns topic summaries, not ranked links. GET /v1/duckduckgo/search returns organic results and paging at 1 credit per query.

  2. Google Images API: Search Image Results as JSON

    One GET to /v1/google-images/images returns image results as JSON for 1 credit: parameters, cURL and Python calls, a real response and licensing notes.

  3. Google Search API: Get Search Results as JSON

    Call GET /v1/google-search/search for organic results as JSON at 1 credit a call. Parameters, a real recorded response and the cost in credits.

Start with 1,000 free credits

No password to set. We email you a sign-in link, and your key works on every API.

No credit card. 1,000 free credits a month.