# eBay sold prices in Google Sheets (with auto-refresh)

URL: https://ebaysoldlistingsapi.com/blog/ebay-sold-prices-google-sheets

Updated: 2026-09-29



Put live eBay sold prices into Google Sheets with a custom =EBAYSOLD() function in Apps Script: median price, sale count, and a refreshable comps tab.



Resellers live in spreadsheets. This guide adds a custom `=EBAYSOLD()` function to Google Sheets so any cell can show the median sold price for an item, plus a script that fills a full comps tab.

### 1. Add the script

In your sheet open Extensions, Apps Script, paste this, and save:

```
const API = "https://api.ebaysoldlistingsapi.com/scrape";
const KEY = PropertiesService.getScriptProperties().getProperty("EBAY_SOLD_API_KEY");

function fetchSold_(keyword, site) {
  const cache = CacheService.getScriptCache();
  const ck = (site || "ebay.com") + "|" + keyword;
  const hit = cache.get(ck);
  if (hit) return JSON.parse(hit);
  const url = API + "?keyword=" + encodeURIComponent(keyword) + "&ebaySite=" + (site || "ebay.com");
  const res = UrlFetchApp.fetch(url, { headers: { Authorization: "Bearer " + KEY }, muteHttpExceptions: true });
  if (res.getResponseCode() !== 200) throw new Error(JSON.parse(res.getContentText()).error);
  const prices = JSON.parse(res.getContentText()).results
    .map((r) => Number(r.soldPrice)).filter((n) => n > 0).sort((a, b) => a - b);
  cache.put(ck, JSON.stringify(prices), 21600); // 6 hours
  return prices;
}

/**
 * Median eBay sold price for a keyword.
 * @param {string} keyword Search term, e.g. "steam deck oled"
 * @param {string} site Optional marketplace, e.g. "ebay.co.uk"
 * @customfunction
 */
function EBAYSOLD(keyword, site) {
  const p = fetchSold_(keyword, site);
  if (!p.length) return "no sales";
  const m = Math.floor(p.length / 2);
  return p.length % 2 ? p[m] : (p[m - 1] + p[m]) / 2;
}

/** Number of completed sales found. @customfunction */
function EBAYSOLDCOUNT(keyword, site) {
  return fetchSold_(keyword, site).length;
}
```

Then open Project Settings, Script properties and add `EBAY_SOLD_API_KEY` with your key, so it never sits in a cell.

### 2. Use it

A: Item | B: Formula | Result
--- | --- | ---
steam deck oled | `=EBAYSOLD(A2)` | median sold price
shure sm7b | `=EBAYSOLD(A3)` | median sold price
barbour jacket | `=EBAYSOLD(A4, "ebay.co.uk")` | median in GBP
ps5 slim | `=EBAYSOLDCOUNT(A5)` | number of sales

Results are cached for six hours, so reopening the sheet does not spend requests. Each uncached keyword uses one request from your plan.

### 3. Full comps tab from CSV

For every individual sale instead of one number, pull the CSV version of the endpoint into a tab:

```
function importComps() {
  const kw = SpreadsheetApp.getActive().getSheetByName("Inputs").getRange("A1").getValue();
  const res = UrlFetchApp.fetch(API + "?format=csv&keyword=" + encodeURIComponent(kw),
    { headers: { Authorization: "Bearer " + KEY } });
  const rows = Utilities.parseCsv(res.getContentText());
  const sh = SpreadsheetApp.getActive().getSheetByName("Comps") || SpreadsheetApp.getActive().insertSheet("Comps");
  sh.clearContents();
  sh.getRange(1, 1, rows.length, rows[0].length).setValues(rows);
}
```

Add a time-driven trigger (Triggers, Add trigger, Time-driven) to refresh it daily. For a complete setup with a Keywords tab, one row per sale, a menu and a daily trigger, see pull eBay sold prices into Google Sheets automatically (https://ebaysoldlistingsapi.com/blog/pull-ebay-sold-prices-into-google-sheets).

Q: Can I get eBay sold prices in Google Sheets for free?
A: Yes, within the free plan's 50 requests a month. With six-hour caching, that covers a small inventory sheet.

Q: Why not IMPORTXML on the eBay sold page?
A: eBay blocks automated page fetches from Google's servers and changes its markup often, so IMPORTXML breaks. An API returns stable JSON or CSV.

Q: Does it work in Excel?
A: Yes. In Excel use Data, From Web with the CSV URL (format=csv) and an Authorization header through Power Query.
