Amazon Offers API

POST /v1/offers returns every offer for up to 100 ASINs (price, shipping, condition, seller, FBA, buy box), and GET /v1/products/{id}/offers does the same for one ASIN.

POST /v1/offers returns every offer for up to 100 ASINs (price, shipping, condition, seller, FBA, buy box), and GET /v1/products/{id}/offers does the same for one ASIN.

Overview

The Product API gives you the buy box. This endpoint goes one level down, to individual offers: who else sells the item, at what price, in what condition and who ships it. One marketplace per call ("marketplace": "us" by default; the others are coming soon, see Marketplaces). The response is the same envelope as /v1/products: platform, marketplace, results, stats, credits.

Endpoint

Answers

Per call

Credits

POST /v1/offers

Every offer for each ASIN

1–100 ASINs

5 per ASIN

GET /v1/products/{id}/offers

The same, for one ASIN

1 ASIN

5

Always 200, failures are free: A well-formed request is answered 200 even if every item came back unavailable. Branch on each result's status. Items that are unavailable (we could not get an answer this time) are refunded; duplicates are fetched and charged once.

Get every offer

POST https://api.scrapely.dev/v1/offers
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{ "asins": string[], "condition"?: "new" | "used" | "all", "marketplace"?: "us", "platform"?: "amazon" }

Parameter

Type

Description

asins

string[]

Required. 1 to 100 ASINs (upper-cased, de-duplicated; empty strings ignored).

condition

string

all (default), new, or used (every non-new condition: used, renewed/refurbished, collectible).

cURL

curl -X POST "https://api.scrapely.dev/v1/offers" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"asins":["B0009KNLV6","BZZZZZZZZZ"],"condition":"all"}'

Python

import requests

r = requests.post(
    "https://api.scrapely.dev/v1/offers",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"asins": ["B0009KNLV6"], "condition": "new"},
    timeout=180,
)
for res in r.json()["results"]:
    for o in res["offers"]:
        print(res["asin"], o["price"], o.get("shipping"), o["seller"]["name"], "FBA" if o["fulfillment"]["isFba"] else "FBM")

Node.js

const res = await fetch('https://api.scrapely.dev/v1/offers', {
  method: 'POST',
  headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({ asins: ['B0009KNLV6'], condition: 'new' }),
  signal: AbortSignal.timeout(180_000),
});
const { results } = await res.json();
const cheapestFba = results[0].offers.filter((o) => o.fulfillment.isFba).sort((a, b) => a.price - b.price)[0];

GET alias

curl "https://api.scrapely.dev/v1/products/B0009KNLV6/offers?condition=new" \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "platform": "amazon",
  "marketplace": "us",
  "results": [
    {
      "asin": "B0009KNLV6",
      "id": "B0009KNLV6",
      "status": "ok",
      "fetchedAt": "2026-10-16T14:02:11.402Z",
      "buyboxOfferListingId": "Rk9vX3dqYlR4Q0pZcWt3dmlmZnpPOFZZJTJCUmN3dE92cmlMQ0o0R2ZtS1hYSjdNSmhqWWVEdkQ%3D",
      "offers": [
        {
          "offerListingId": "Rk9vX3dqYlR4Q0pZcWt3dmlmZnpPOFZZJTJCUmN3dE92cmlMQ0o0R2ZtS1hYSjdNSmhqWWVEdkQ%3D",
          "price": 77.43,
          "currency": "USD",
          "priceDisplay": "$77.43",
          "shipping": 0,
          "condition": "new",
          "seller": {
            "id": "ATVPDKIKX0DER",
            "name": "Amazon.com"
          },
          "fulfillment": {
            "isFba": true,
            "fulfillerName": "Amazon.com"
          },
          "isBuybox": true,
          "delivery": "FREE delivery Tuesday, October 21 on orders shipped by Amazon over $35"
        },
        {
          "offerListingId": "cW1aMWx0dDNPcEdnbUo2UnBQOGJzcFJIVWZPRWlqUiUyRkR1NUwlMkZPRzZTJTJCQ3J6cFk%3D",
          "price": 71.5,
          "currency": "USD",
          "priceDisplay": "$71.50",
          "shipping": 5.99,
          "condition": "new",
          "seller": {
            "id": "A2R2RITDJNW1Q6",
            "name": "Retro Lunch Co",
            "rating": 4.5,
            "ratingCount": 1287
          },
          "fulfillment": {
            "isFba": false,
            "fulfillerName": "Retro Lunch Co"
          },
          "isBuybox": false,
          "availability": "Only 3 left in stock - order soon.",
          "delivery": "$5.99 delivery October 24 - 28"
        }
      ]
    },
    {
      "asin": "BZZZZZZZZZ",
      "id": "BZZZZZZZZZ",
      "status": "not_found",
      "fetchedAt": "2026-10-16T14:02:10.977Z",
      "offers": []
    }
  ],
  "stats": {
    "requested": 2,
    "ok": 1,
    "partial": 0,
    "notFound": 1,
    "unavailable": 0,
    "elapsedMs": 2210
  },
  "credits": 10
}

Field

Description

status

ok (charged; offers may be empty), not_found (Amazon has no such product; charged), unavailable (we could not get an answer this time, or the call ran out of time; refunded, retry later).

buyboxOfferListingId

The featured (buy-box) offer, when there is one. That offer also has isBuybox: true. It is reported even when condition filters it out of offers.

offers[].offerListingId

Identifies this exact offer.

offers[].price / shipping

In offers[].currency, the marketplace's currency (USD on us). shipping is 0 for free delivery and absent when Amazon does not state it.

offers[].condition

new, used_like_new, used_very_good, used_good, used_acceptable, refurbished, collectible_like_new, …; conditionNote is the seller's comment.

offers[].seller

id (merchant id; on us, ATVPDKIKX0DER is Amazon itself), name, and the star rating / ratingCount when shown.

offers[].fulfillment

isFba: shipped by Amazon. fulfillerName: who ships it.

availability, delivery

The stock line ("Only 3 left in stock") and the delivery promise, as Amazon words them, when present.

Up to 31 offers per ASIN: You get every offer for the ASIN, up to 31: the featured (buy-box) offer first, then the rest cheapest first. Offers beyond that are the most expensive ones and rarely matter for pricing. condition is applied to those offers, so on listings with very many offers a used request may not see every used offer.

Duration: a 100-ASIN call usually takes well under a minute; allow up to 180 s. ASINs not reached before the call runs out of time come back unavailable and are refunded. Uses one concurrency slot.

Updated