Every trawl API is plain HTTPS: send a request with your key, get JSON back. One key and one request pool works across all of them.

Getting started

Create a key in the console — the free tier includes 100 requests a month, no card needed — then make your first call:

curl "https://api.trawl.dev/ebay/v1/sold?query=iphone+15+pro+256gb&condition=used" \
  -H "x-api-key: YOUR_KEY"

Prefer to poke around first? The playground runs real requests from your browser.

Authentication

Send your key in the x-api-key header on every request. Header names are case-insensitive. Keys are account-wide — one key works on every trawl API — and can be deleted at any time from the console.

x-api-key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Never put the key in a query string — query strings end up in server logs, browser history and Referer headers. And never ship it in client-side code: call the API from your backend, with the key in an environment variable. A key that leaks can be deleted and reminted in seconds from the console.

Plans & usage

Your plan includes a monthly request allowance shared across all trawl APIs — one pool, spendable anywhere — plus a per-second request rate. Only successful (2xx) responses count against the allowance; errors are free and don't count toward the rate either. The window follows your billing cycle: it resets when your subscription starts, renews, or changes plan (free accounts reset on the first of each month, UTC). You're welcome to spend the whole month's allowance as fast as your rate allows.

PlanRequests / monthReq / secSupport
Free1001Community
Basic2,0002Email · 24h
Pro10,0005Email · 24h
Business50,00010Dedicated Slack channel

Every response reports your standing:

HeaderMeaning
X-RateLimit-LimitRequests included in your plan per month.
X-RateLimit-RemainingRequests left this month.
X-RateLimit-ResetWhen your allowance window resets (Unix timestamp — your billing period end).

A 429 means one of two things: going over your per-second rate (the response carries a Retry-After header — wait and retry), or a spent monthly allowance (no Retry-After — wait for the reset, or upgrade for a bigger pool). Need more than the largest tier? Talk to us about a custom plan.

Errors

Successful requests return 200. Everything else returns JSON with a single error field explaining what went wrong:

{ "error": "min_price must be <= max_price" }
StatusMeaning
400A parameter failed validation — the message names the field and the rule it broke.
403Missing, invalid, or deleted API key.
404Nothing found — an unknown path or resource.
429Two cases: a Retry-After header means you hit your plan's per-second rate — wait that long and retry. No Retry-After means the monthly allowance is spent — upgrade, or wait for X-RateLimit-Reset. Neither counts as a billed request.
500Internal error on our side.
503Search backend temporarily unavailable — safe to retry shortly.
API

eBay API

Sold-listings data: search 80+ million real completed eBay sales across the US and UK marketplaces — final price, sale date, condition and shipping for every item that actually sold. eBay itself only shows 90 days of sold history with barely any filtering; this keeps the history and adds the query controls.

Base URL: https://api.trawl.dev/ebay/v1

GEThttps://api.trawl.dev/ebay/v1/sold

Finds sold listings whose title contains every word in your query, in any order — the same matching eBay's own search uses. Results are always newest-first.

Parameters

ParameterTypeDescription
queryrequiredstringWords that must all appear in the listing title, in any order.
sitestringMarketplace to search. Defaults to EBAY_US.
excludestringWords that must NOT appear in the title — filters out accessories, broken units, lots.
categorystringRestrict to one eBay leaf category (e.g. 9355 for Cell Phones & Smartphones). Find ids via /categories.
min_pricenumberMinimum sale price.
max_pricenumberMaximum sale price.
conditionstringOne or more of new, new_other, open_box, used, refurbished, parts, unknown. Comma-separate for several.
date_fromstringEarliest sale date, inclusive (YYYY-MM-DD).
date_tostringLatest sale date, inclusive (YYYY-MM-DD).
limitnumberResults per page, 1–240. Results are always newest-first.
pagenumberPage number, 1–50 (page × limit is capped at 15,000).

Response

{
  "site": "EBAY_US",
  "currency": "USD",
  "query": [
    "iphone",
    "13",
    "pro"
  ],
  "filters": {
    "condition": [
      "used"
    ]
  },
  "page": 1,
  "count": 240,
  "took_ms": 41,
  "results": [
    {
      "item_id": "256637082114",
      "title": "Apple iPhone 13 Pro 256GB Graphite Unlocked",
      "sale_price": 525,
      "shipping_price": 0,
      "currency": "$",
      "condition": "Pre-Owned",
      "condition_normalized": "used",
      "buying_format": "Buy It Now",
      "date_sold": "2026-07-18T00:00:00.000Z",
      "item_link": "https://www.ebay.com/itm/256637082114",
      "image_url": "https://i.ebayimg.com/images/g/abc/s-l500.webp",
      "location": "United States",
      "seller_name": "techresale",
      "seller_feedback_count": 1842,
      "seller_feedback_percent": 99.6,
      "categoryId": "9355"
    }
  ]
}
GEThttps://api.trawl.dev/ebay/v1/categories

Look up eBay leaf categories by name, busiest first — use the returned categoryId as the category filter on /sold. Matching covers the category's full path, a numeric query looks up that exact id, and ids differ per marketplace, so pass the same site you'll search with. Note: eBay has no per-brand categories — Pokémon or baseball cards live under generic ones like CCG Individual Cards (183454); narrow to a brand with query terms on /sold.

Parameters

ParameterTypeDescription
queryrequiredstringWords to match against category names and their parent path — every word must appear, in any order. Case- and accent-insensitive. A numeric query looks up that exact category id instead.
sitestringMarketplace: EBAY_US or EBAY_GB. Defaults to EBAY_US. Category ids differ per marketplace — pass the same site you'll search with.

Response

{
  "site": "EBAY_US",
  "total": 38,
  "count": 5,
  "categories": [
    {
      "categoryId": "261328",
      "name": "Trading Card Singles",
      "group": "Sports Mem, Cards & Fan Shop"
    },
    {
      "categoryId": "183050",
      "name": "Trading Card Singles",
      "group": "Collectibles"
    },
    {
      "categoryId": "261329",
      "name": "Trading Card Lots",
      "group": "Sports Mem, Cards & Fan Shop"
    },
    {
      "categoryId": "261332",
      "name": "Sealed Trading Card Boxes",
      "group": "Sports Mem, Cards & Fan Shop"
    },
    {
      "categoryId": "261330",
      "name": "Trading Card Sets",
      "group": "Sports Mem, Cards & Fan Shop"
    }
  ]
}

More APIs coming — same key, same pool, same docs page. Need a custom integration? Contact us.