Getting started

Amazon Data API response format

Flat JSON objects with stable field names. No envelope, no data.data, no per-endpoint surprises in how success is signalled.

Shape

Success is the HTTP status. A 2xx body is the payload itself — there is no success: true flag to check. Errors always carry a top-level error object (or detail for validation).

GET /products/search — 200 OK
{
  "page": 1,
  "sort": null,
  "count": 20,
  "query": "wireless mouse",
  "results": [
    {
      "url": "https://www.amazon.com/dp/B07CMS5Q6P/ref=sr_1_1_sspa",
      "asin": "B07CMS5Q6P",
      "badge": "Best Seller",
      "image": "https://m.media-amazon.com/images/I/51sg9BLSMTL.jpg",
      "price": {
        "amount": 29.99,
        "display": "$29.99",
        "currency": "USD",
        "list_price": 49.99
      },
      "prime": false,
      "title": "Logitech G305 Lightspeed Wireless Gaming Mouse - Black | HERO sensor, 12,000 DPI, Six programmable buttons, 250-hour battery, On-board memory",
      "rating": 4.6,
      "delivery": "FREE delivery Mon, Aug 10 on $35 of items shipped by Amazon",
      "position": 4,
      "sponsored": true,
      "reviews_count": 39364,
      "bought_past_month": "10K+ bought in past month"
    },
    {
      "url": "https://www.amazon.com/dp/B005EJH6Z4/ref=sr_1_2_ffob_sspa",
      "asin": "B005EJH6Z4",
      "badge": null,
      "image": "https://m.media-amazon.com/images/I/61YQeAUIboL.jpg",
      "price": {
        "amount": 12.58,
        "display": "$12.58",
        "currency": "USD",
        "list_price": null
      },
      "prime": false,
      "title": "Amazon Basics 2.4 GHz Wireless Optical Computer Mouse with USB Nano Receiver",
      "rating": 4.5,
      "delivery": "FREE delivery Mon, Aug 10 on $35 of items shipped by Amazon",
      "position": 5,
      "sponsored": true,
      "reviews_count": 69507,
      "bought_past_month": "10K+ bought in past month"
    }
  ],
  "marketplace": "US",
  "has_next_page": true,
  "total_results": 42555
}

Field conventions

Prices

Always an object, never a bare string or float. display is what Amazon showed; amount is the parsed number in currency. list_price is the struck-through price where one exists, otherwise null.

Nulls mean “absent upstream”

A null is never a parsing shortcut — it means Amazon did not serve that field for that listing. badge: null means no badge; author: null on a review means Amazon rendered a linkless variant with no reviewer name. Treat null and missing as the same thing.

Lists are always present

Array fields are [] when empty, never null. You can iterate without a guard. Paired counts (count, total_results) always match the array you were given.

count vs total_results

FieldMeaning
countItems in this response.
total_resultsAmazon's claimed total across all pages. Approximate, and it drifts between requests — treat it as a hint, not a contract.
has_next_pageAuthoritative. Use this to drive pagination, not arithmetic on total_results.

The note field

Some Amazon surfaces are client-rendered or gated behind encrypted lazy-load calls. Where we cannot extract something, the response says so explicitly rather than returning a plausible-looking empty object.

GET /influencers/posts — 200 OK
{
  "handle": "thehomeedit",
  "marketplace": "US",
  "count": 0,
  "posts": [],
  "note": "Influencer storefronts render posts client-side; the served HTML contains no post nodes."
}
Check note before treating count: 0 as “this creator has no posts”. The endpoints that can return one are flagged in the API Reference.

Diagnostic headers

HeaderExampleMeaning
X-CacheHITServed from the in-process cache.
X-Response-Time-Ms412Server-side processing time.
X-Credits-Cost1Credits this call consumed.
X-Credits-Remaining24831Credits left this period.
X-Credits-Reset2026-09-03T…When the quota resets.
X-RateLimit-Limit15Requests per second on your plan.

Reacting to your own budget

budget.py
response = requests.get(url, headers=HEADERS, params=params)

remaining = int(response.headers.get("X-Credits-Remaining", 0))
if remaining < 1000:
    logger.warning("Credits low: %s left, resets %s",
                   remaining, response.headers["X-Credits-Reset"])

if response.headers.get("X-Cache") == "MISS":
    metrics.timing("amazon.upstream_ms", int(response.headers["X-Response-Time-Ms"]))

Content type and encoding

Everything is application/json; charset=utf-8. Titles and review bodies contain the original Unicode — emoji, CJK, RTL scripts and typographic quotes come through unescaped. Responses are gzip-compressed when your client advertises support.

CORS

The API sends Access-Control-Allow-Origin: * and exposes the diagnostic headers above, so browser clients can read them. That said — calling the API directly from a browser means shipping your key to every visitor. Proxy through your own backend.