Back to blog

Compare eBay US, UK, and Germany Listings Without Mixing Currencies

By SoldFetch Engineering7 min read

Build separate eBay marketplace cohorts, preserve USD, GBP, and EUR amounts, and make optional currency conversions explicit and reproducible.

Compare eBay US, UK, and Germany Listings Without Mixing Currencies

Comparing eBay listings across the US, UK, and Germany starts with three separate datasets. Each has its own search wording, condition descriptions, currency, and retrieval time. Combining the amounts into one column before resolving those differences produces a number that is difficult to interpret.

SoldFetch can search ebay.com, ebay.co.uk, and ebay.de when those marketplaces are enabled. This guide shows how to plan a comparable search, keep the raw observations separate, and add an optional currency-converted view without overwriting the source data.

The examples use synthetic records and hypothetical user-supplied exchange rates. They are a reproducible calculation exercise, not live marketplace prices or an estimate of resale profit.

Define one product and three comparable searches

Start with a stable product identifier: model, capacity, generation, and relevant accessories. A broad phrase such as “Sony headphones” can find several products before differences between marketplaces even enter the analysis.

For a first baseline, use the same model query on each site and the same sold/active mode, condition choice, sort order, page budget, and requested count. A model identifier such as sony wh-1000xm5 is a reasonable starting point for discovery, but it still needs listing review.

Cohort ebaySite Baseline keyword Requested condition
US ebay.com sony wh-1000xm5 used
UK ebay.co.uk sony wh-1000xm5 used
Germany ebay.de sony wh-1000xm5 used

Keep localized exploratory queries separately. For example, adding Kopfhörer on the German site might change the result population. It is useful research, but the new query needs its own recorded parameters and reviewed cohort rather than being silently combined with the baseline.

Record marketplace context with each request

Check capabilities for current enabled sites and data availability. Input validation recognizes more site names than a deployment necessarily enables. Do not infer availability from a country appearing in a dropdown or from a successful request to another site.

Use GET /v1/scrape with explicit keyword, ebaySite, sold=true, and the shared request controls. itemCondition=used is broad source filtering; it does not establish that three listings have equivalent wear or bundle contents. Keep exactMatch=true for excluding explicitly flagged loose matches, while still reviewing product identity yourself.

Persist the request site with every row. The application knows which site it requested, and that context should survive normalization and CSV export. Keep item IDs as strings and use (ebaySite, itemId) as a deduplication key within a comparison run.

The selected storefront is also different from a seller's physical location or a listing's delivery eligibility. SoldFetch does not support the unavailable location filters by accepting arbitrary itemLocation settings. Retain returned location wording as context without treating it as verified delivery coverage.

Preserve native currencies and unknown shipping

For sold results, keep soldPrice beside soldCurrency. For active results, use currentPrice and currentCurrency and create a separate analysis. Asking prices and sold-search observations answer different questions and should not share one median.

Read currency from each row. A marketplace name is context, not permission to replace a missing currency with USD, GBP, or EUR. Keep missing amounts and currencies out of arithmetic until they are resolved.

Store shippingPrice and shippingCurrency separately. Only add shipping when both amounts are known, finite, nonnegative, and denominated in the same currency. A null shipping amount means unknown; it is not zero. A shipping amount in a different currency requires its own explicit conversion decision.

These synthetic examples show why a single total column is insufficient:

Site Displayed item amount Shipping amount Same-currency item + shipping
US 80.00 USD 5.00 USD 85.00 USD
UK 70.00 GBP Unknown Unknown
Germany 90.00 EUR 0.00 EUR, explicitly free 90.00 EUR

The UK row remains useful as an item-price observation, but it cannot enter a complete delivered-price subset. Even the known totals are listing evidence, not a complete checkout quote containing every tax or fee.

Match condition, contents, and observation times

Review model, generation, condition wording, accessories, damage, and multi-item bundles before summarizing. Keep rejected rows and the reason for exclusion. The matching rule should be the same across all three marketplaces even when the source language differs.

Retain both the raw condition and your normalized review category. Mapping every locally worded “used” description to one label can hide significant differences. A missing charging cable or damaged hinge changes the comparison even if the model number matches.

Capture each response's fetchedAt and X-SoldFetch-Data-Fetched-At, plus your ingestion time. Sold searches currently cache for six hours, so requesting three sites consecutively does not guarantee that their underlying evidence was collected consecutively. Show source ages and resample later if the age difference makes the comparison unsuitable.

Source-reported sale dates are unverified, and verified sale-date filters are unavailable. Describe the output as a retrieved snapshot of reviewed listings. Do not label it a complete, synchronized record of transactions in a chosen time window.

Add a conversion layer with explicit inputs

Keep the native report as the primary record. If a reader wants a common-currency view, add a conversion result containing source amount, source currency, rate, rate timestamp, destination currency, and rounding policy.

For this exercise, imagine a user supplies hypothetical rates of 1 GBP = 1.25 USD and 1 EUR = 1.10 USD, with a rate timestamp of 2026-10-24T12:00:00Z. These numbers are illustrative inputs, not historical or current exchange-rate claims.

The Python code below runs entirely offline. The converter returns the rate evidence with the amount, making it harder to mistake a converted view for raw source data:

from decimal import Decimal, InvalidOperation, ROUND_HALF_UP

def amount_or_none(value):
    if value is None:
        return None
    try:
        result = Decimal(str(value))
    except InvalidOperation:
        return None
    return result if result.is_finite() and result >= 0 else None

def same_currency_total(row):
    item = amount_or_none(row.get("soldPrice"))
    shipping = amount_or_none(row.get("shippingPrice"))
    currency = row.get("soldCurrency")
    if item is None or shipping is None or not currency:
        return None
    if currency != row.get("shippingCurrency"):
        return None
    return item + shipping

def convert_to_usd(amount, currency, rates, rate_timestamp):
    value = amount_or_none(amount)
    rate = amount_or_none(rates.get(currency))
    if value is None or rate is None or rate <= 0 or not rate_timestamp:
        raise ValueError("Amount, explicit rate, and timestamp are required")
    return {
        "sourceAmount": str(value), "sourceCurrency": currency,
        "rateToUSD": str(rate), "rateTimestamp": rate_timestamp,
        "convertedUSD": str((value * rate).quantize(
            Decimal("0.01"), rounding=ROUND_HALF_UP)),
    }

Passing the synthetic item amounts 80.00 USD, 70.00 GBP, and 90.00 EUR with rates {"USD": "1", "GBP": "1.25", "EUR": "1.10"} produces 80.00, 87.50, and 99.00 USD respectively. These are item-only conversions. They do not fill the missing UK shipping cost or make unlike conditions comparable.

Publish three cohorts before one comparison

For each marketplace, show the reviewed count, native currency, median displayed item amount, retrieval range, and excluded/pending count. Do not average those three medians into a supposed global market price.

If you include conversion, label the secondary view and repeat its rate timestamp. Use the same comparison definition across sites: displayed item amounts or a complete same-currency item-plus-shipping subset. Show how many rows remain under that definition so missing shipping does not disappear from the report.

Preserve data-quality warnings. A displayed sold-listing amount can differ from an accepted offer, and a range lower bound should not enter a single-price summary. Currency conversion changes the unit of expression; it does not improve the underlying price evidence or establish profitability.

Run a small reviewable comparison first

Start with one model and a bounded request budget across the three sites. Test locally with missing currency, mixed shipping currencies, free shipping, malformed amounts, a different bundle, and duplicate listings. Confirm that each native cohort stays separate and every converted amount retains its rate evidence.

Read the marketplace concepts, search reference, and data-quality guide. Then create an API key and collect a small sample for manual review. A useful comparison lets readers see exactly what was searched, matched, retrieved, and converted.

Download the offline example

Download the complete Python example. The companion includes synthetic fixtures and offline checks. It makes no network requests.

Topics

#ebay-api#cross-marketplace-research#python#data-quality

Related posts

AI agent or LLM? Read this page as Markdown