Integration Guide
How to Check Resale Margin Across eBay, AliExpress, and Temu
ChatGPT's answer to 'can I resell this AliExpress item on eBay' is: search eBay's UI by hand and count sold listings. Here's the automatable version — batch price-check all three marketplaces and get a margin table back.
Written by Alex P.
- eBay
- AliExpress
- Temu
- price comparison
- arbitrage
- marketplace pricing
Ask an AI assistant how to check whether a cheap AliExpress or Temu item is worth reselling on eBay, and the answer is a manual routine: search eBay by buyer-style keywords, filter to sold and completed listings, eyeball the typical sold price. That’s a reasonable one-off check. It doesn’t scale past the first handful of products, and it’s exactly the kind of repetitive lookup that a batch price API replaces with one request per marketplace.
This builds that: a list of candidate products, priced on their source marketplace and checked against current eBay asking prices, with the margin math done for you — and an honest caveat about what “checked against eBay” actually means here.
Price a candidate list on its source marketplace
AliExpress and Temu both take up to a batch of products per call, each identified by product id, URL, or a specific variant:
const API_KEY = process.env.FETCHLAYER_API_KEY;
async function priceAliExpress(products, shipTo = 'US') {
const res = await fetch('https://api.fetchlayer.dev/aliexpress/product-prices', {
method: 'POST',
headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ products, shipTo, currency: 'USD' }),
});
return (await res.json()).items;
}
async function priceTemu(items, market = 'US') {
const res = await fetch('https://api.fetchlayer.dev/temu/price-check', {
method: 'POST',
headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
// Always include skuId when you have it — without it, Temu looks up the
// default variant first, which costs significantly more per item.
body: JSON.stringify({ items, market }),
});
return (await res.json()).items;
}
AliExpress returns price (lowest current variant), priceMax, and originalPrice (pre-discount) per product — worth keeping all three, since a source item currently on sale has a different real margin than its regular price would suggest. Temu returns price.amount in the storefront’s own currency, plus availability.
Check the resale ceiling on eBay
There’s no “sold comps” endpoint here — search-listings returns active listings, sorted by price. Treat the lowest active asking prices as a resale ceiling estimate, not proof of what actually sells; that distinction matters and is worth keeping explicit in your own data rather than glossing over:
async function checkEbayAskingPrice(query) {
const res = await fetch('https://api.fetchlayer.dev/ebay/search-listings', {
method: 'POST',
headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, sort: 'price_lowest', condition: ['new'], limit: 20 }),
});
const { listings } = await res.json();
if (!listings.length) return null;
const prices = listings.map((l) => l.price.amount).sort((a, b) => a - b);
return {
lowestAsking: prices[0],
medianAsking: prices[Math.floor(prices.length / 2)],
activeListingCount: listings.length,
};
}
A high activeListingCount at a low medianAsking is itself useful signal even without sold data — it means a lot of sellers are already competing on this exact item, which compresses margin regardless of what any one of them is actually moving.
Putting it together: a margin table
async function buildMarginTable(candidates) {
const results = [];
for (const candidate of candidates) {
const sourcePrice = candidate.source === 'aliexpress'
? (await priceAliExpress([{ product: candidate.productId }]))[0]?.price
: (await priceTemu([{ goodsId: candidate.goodsId, skuId: candidate.skuId }]))[0]?.price?.amount;
const ebayData = await checkEbayAskingPrice(candidate.searchQuery);
if (sourcePrice == null || !ebayData) {
results.push({ ...candidate, status: 'incomplete' });
continue;
}
const grossMargin = ebayData.lowestAsking - sourcePrice;
results.push({
...candidate,
sourcePrice,
ebayLowestAsking: ebayData.lowestAsking,
ebayMedianAsking: ebayData.medianAsking,
ebayListingCount: ebayData.activeListingCount,
grossMargin,
marginPercent: ((grossMargin / ebayData.lowestAsking) * 100).toFixed(1),
status: 'ok',
});
}
return results.sort((a, b) => (b.grossMargin ?? -Infinity) - (a.grossMargin ?? -Infinity));
}
grossMargin here is asking-price minus source-price — it excludes eBay’s own selling fees, shipping cost, and payment processing, none of which any of these APIs report. Treat it as a screening number to rank candidates, not a final profit figure.
Re-checking a shortlist on a schedule
Once you’ve shortlisted a handful of promising candidates, poll them rather than re-running the full search — the source price is what typically moves first:
import { readFile, writeFile } from 'node:fs/promises';
const STATE_FILE = './arbitrage-watchlist.json';
async function checkWatchlist(watchlist) {
const table = await buildMarginTable(watchlist);
let history = [];
try {
history = JSON.parse(await readFile(STATE_FILE, 'utf8'));
} catch {}
history.push({ date: new Date().toISOString().slice(0, 10), table });
await writeFile(STATE_FILE, JSON.stringify(history, null, 2));
const improved = table.filter((r) => r.status === 'ok' && r.grossMargin > 0);
console.log(`${improved.length}/${table.length} candidates still show positive margin.`);
}
Practical notes
- eBay’s
priceis always reported in US dollars in bothfastandexactmode onprice-check, specifically so a series of checks over time stays comparable even if you’re tracking a listing in a seller’s non-US currency (listingPricecarries that, separately). - Temu’s
variantLookedUp: trueon a result means the default variant was resolved for you because noskuIdwas sent — store theskuIdthat comes back and send it on the next check to avoid paying for that lookup again. - AliExpress’s
totalStockis worth checking before ranking on margin alone. A product with strong margin and very lowtotalStockacross variants isn’t a repeatable opportunity — check it before treating a one-time price gap as a durable one.
Next Steps
- eBay API · AliExpress API · Temu API
- Get a free API key — no credit card required