Offers & offer check

POST /v1/offers lists every seller on a listing with price, shipping, condition and fulfilment; POST /v1/offers/check says whether exact offers can still be bought.

Embed
Preview of the card
<a href="https://scrapelyserp.com/docs/offers"><img src="https://scrapelyserp.com/docs/_api/public/orgs/affc5b0f-d3c2-423a-8143-9d10db5736ae/spaces/981e6275-da3f-446c-82de-889f59c83b6f/pages/6de36928-b8eb-4510-9bdb-1da55bf54a83/social-card.svg?v=3e7ae33eec8b" alt="Offers &amp; offer check" width="600" height="315"></a>

POST /v1/offers lists every seller on a listing with price, shipping, condition and fulfilment; POST /v1/offers/check says whether exact offers can still be bought.

Overview

Products give you the featured (buy-box) offer. These endpoints go one level down, to individual offers.

Endpoint

Answers

Per call

Credits per item

Live on

POST /v1/offers

Every offer on each listing

1–100 ids

1 or 3

Amazon (us)

GET /v1/products/{id}/offers

The same, for one id

1 id

1 or 3

Amazon (us)

POST /v1/offers/check

Can each exact offer be bought now

1–2,000 offers

0.5

Amazon (us)

All three take platform and marketplace like every item endpoint and return the same envelope. Where they are not live yet, they answer 501 with "coming_soon": true and charge nothing.

List every offer

POST https://api.scrapelyserp.com/v1/offers
Authorization: Bearer $SCRAPELY_API_KEY
Content-Type: application/json

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

Field

Type

Description

ids

string[], required

1 to 100 item ids (asins also works on Amazon). Duplicates are fetched and charged once.

condition

string

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

platform, marketplace

string

As for Products.

cURL

curl -X POST "https://api.scrapelyserp.com/v1/offers" \
  -H "Authorization: Bearer $SCRAPELY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "amazon",
    "ids": ["B0009KNLV6", "BZZZZZZZZZ"],
    "condition": "new"
  }'

Python

import os
import requests

HEADERS = {"Authorization": f"Bearer {os.environ['SCRAPELY_API_KEY']}"}

r = requests.post(
    "https://api.scrapelyserp.com/v1/offers",
    headers=HEADERS,
    json={
        "platform": "amazon",
        "ids": ["B0009KNLV6", "BZZZZZZZZZ"],
        "condition": "new",
    },
    timeout=180,
)
r.raise_for_status()
data = r.json()
for res in data["results"]:
    for o in res["offers"]:
        print(res["id"], o["price"], o.get("shipping"), o["seller"]["name"])

Node.js

const res = await fetch('https://api.scrapelyserp.com/v1/offers', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SCRAPELY_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    platform: 'amazon',
    ids: ['B0009KNLV6', 'BZZZZZZZZZ'],
    condition: 'new',
  }),
  signal: AbortSignal.timeout(180_000),
});
const data = await res.json();
const cheapest = data.results[0].offers.toSorted((a, b) => a.price - b.price)[0];

GET (one id)

curl -G "https://api.scrapelyserp.com/v1/products/B0009KNLV6/offers" \
  -H "Authorization: Bearer $SCRAPELY_API_KEY" \
  -d platform=amazon \
  -d condition=new

Response

{
  "platform": "amazon",
  "marketplace": "us",
  "results": [
    {
      "asin": "B0009KNLV6",
      "id": "B0009KNLV6",
      "status": "ok",
      "fetchedAt": "2026-10-16T14:02:11.402Z",
      "buyboxOfferListingId": "Rk9vX3dqYlR4Q0pZcWt3dmlmZnpPOFZZJTJCUmN3dE92cmlMQ0o0R2ZtS1hYSjdNSmhqWWVEdkQ%3D",
      "totalOffers": 14,
      "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": 4
}

Field

Description

status

ok (charged; offers may be empty), not_found (charged), unavailable (refunded; retry later).

totalOffers

Offers on the listing in every condition, the featured one included. 1 or less: charged the single-offer rate.

buyboxOfferListingId

The featured offer, when there is one (that offer also has isBuybox: true). Reported even when condition filters it out.

offers[].offerListingId

Identifies this exact offer. Use it with offer check.

offers[].price, shipping, currency

In the marketplace currency. shipping is 0 for free delivery and absent when not stated.

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, name, and the star rating / ratingCount when shown.

offers[].fulfillment

isFba (shipped by the retailer) and fulfillerName.

offers[].availability, delivery

The stock line and delivery promise, in the retailer's words, when present.

  • Price: 1 credit for a listing with one offer (or none), 3 for one with more. About half of all listings have a single seller. A call reserves 3 per id and refunds the difference.

  • Up to 31 offers per listing: the featured offer first, then the rest cheapest first. condition filters those, so on very crowded listings a used request may not see every used offer.

  • Timing: a 100-id call usually takes well under a minute; allow 180 seconds. Ids not reached in time come back unavailable and are refunded.

Check specific offers

Once you know which offers matter, ask whether each one can still be bought, as often as you like. Take the offerListingId from a products result (buybox.offerListingId on Amazon lite and full) or from /v1/offers, and send it with its item id. 0.5 credit per offer, rounded up once per call.

POST https://api.scrapelyserp.com/v1/offers/check
Authorization: Bearer $SCRAPELY_API_KEY
Content-Type: application/json

{
  "platform": "amazon",
  "marketplace"?: "us",
  "offers": [{ "asin": string, "offerListingId": string }]
}

cURL

curl -X POST "https://api.scrapelyserp.com/v1/offers/check" \
  -H "Authorization: Bearer $SCRAPELY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "amazon",
    "offers": [
      {
        "asin": "B0009KNLV6",
        "offerListingId": "pQ4/z9Lr0sT="
      }
    ]
  }'

Python

import os
import requests

HEADERS = {"Authorization": f"Bearer {os.environ['SCRAPELY_API_KEY']}"}

r = requests.post(
    "https://api.scrapelyserp.com/v1/offers/check",
    headers=HEADERS,
    json={
        "platform": "amazon",
        "offers": [{"asin": "B0009KNLV6", "offerListingId": "pQ4/z9Lr0sT="}],
    },
    timeout=120,
)
r.raise_for_status()
data = r.json()
print([r["buyable"] for r in data["results"]])

Node.js

const res = await fetch('https://api.scrapelyserp.com/v1/offers/check', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SCRAPELY_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    platform: 'amazon',
    offers: [{ asin: 'B0009KNLV6', offerListingId: 'pQ4/z9Lr0sT=' }],
  }),
  signal: AbortSignal.timeout(120_000),
});
const data = await res.json();
console.log(data.results.map((r) => r.buyable));

Response

{
  "platform": "amazon",
  "marketplace": "us",
  "results": [
    {
      "id": "pQ4/z9Lr0sT=",
      "asin": "B0009KNLV6",
      "offerListingId": "pQ4/z9Lr0sT=",
      "status": "ok",
      "fetchedAt": "2026-10-18T19:02:11.402Z",
      "buyable": true
    },
    {
      "id": "Xh7+qT2b/kLm9wQ==",
      "asin": "0060094664",
      "offerListingId": "Xh7+qT2b/kLm9wQ==",
      "status": "ok",
      "fetchedAt": "2026-10-18T19:02:11.402Z",
      "buyable": false
    }
  ],
  "stats": {
    "requested": 2,
    "ok": 2,
    "partial": 0,
    "notFound": 0,
    "unavailable": 0,
    "elapsedMs": 1210
  },
  "credits": 1
}

Field

Description

offers

Required (ids also works). 1 to 2,000 objects { asin, offerListingId }, exactly as the API returned them (a URL-encoded id is decoded). The two must belong together. Duplicates are checked and charged once.

buyable

On ok: true when the exact offer can be bought right now; false when it cannot (pulled, sold out, or not a real offer id).

status

ok (charged) or unavailable (refunded; retry later).

A yes or no, not a price: Scarce, back-ordered and pre-order offers are all buyable: true, and the answer carries no price or stock level: read those from Products. buyable: false does not say why, so keep ids exactly as we returned them.

Timing: 2,000 offers usually take 15–20 seconds. Each call uses one concurrency slot.

Updated