Amazon review data is a rich source of customer sentiment signal, product-improvement hints, and competitive intelligence. Scraping it directly is unreliable thanks to aggressive bot detection and CAPTCHA challenges. Scavio returns the review signal Amazon actually exposes for an ASIN through /api/v1/amazon/product: the aggregate star rating, the exact reviews_count, and a reviews array of per-review metadata (a stable review id, the reviewer name, the date string Amazon renders, and a verified_purchase flag). Be clear about the boundary before you build on it: this pipeline does not return review bodies or per-review star ratings, so it powers rating tracking, review-velocity tracking, and authenticity checks rather than text mining. This tutorial shows how to fetch the signal, measure the verified-purchase share, and snapshot ratings over time.
Prerequisites
- Python 3.8 or higher
- requests library installed
- A Scavio API key
- An Amazon ASIN to fetch review data for
Walkthrough
Step 1: Fetch review signal for a product ASIN
POST the ASIN to /api/v1/amazon/product. The payload arrives under data, carrying rating, reviews_count, and a reviews array of per-review metadata.
def get_review_signal(asin: str) -> dict:
response = requests.post(
"https://api.scavio.dev/api/v1/amazon/product",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"asin": asin, "country": "us"}
)
response.raise_for_status()
product = response.json()["data"]
return {
"asin": product.get("asin"),
"rating": product.get("rating"),
"reviews_count": product.get("reviews_count"),
"reviews": product.get("reviews", []),
}Step 2: Measure the verified-purchase share
verified_purchase is the one authenticity signal on each review record. The share of verified reviews in the sample is a cheap proxy for how trustworthy the rating is.
def verified_share(reviews: list[dict]) -> float:
if not reviews:
return 0.0
verified = sum(1 for r in reviews if r.get("verified_purchase"))
return verified / len(reviews)
signal = get_review_signal("B09G9FPHY6")
print(f"{verified_share(signal['reviews']):.0%} of sampled reviews are verified purchases")Step 3: List the most recent reviewers
Each record carries a stable id, the reviewer name, and Amazon's own date string. Use the ids to diff one run against the next and detect new reviews.
for r in signal["reviews"][:5]:
flag = "verified" if r.get("verified_purchase") else "unverified"
print(f"{r.get('id')} | {r.get('author')} | {r.get('date')} | {flag}")Step 4: Snapshot the rating over time
Because there is no review text, the useful longitudinal signal is drift: append one row per run and watch rating and reviews_count move. Rising volume with a falling rating is the pattern worth alerting on.
import csv
from datetime import date
with open("rating_history.csv", "a", newline="") as f:
csv.writer(f).writerow([
date.today().isoformat(),
signal["asin"],
signal["rating"],
signal["reviews_count"],
])Python Example
import os
import requests
API_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
ENDPOINT = "https://api.scavio.dev/api/v1/amazon/product"
def get_review_signal(asin: str) -> dict:
r = requests.post(ENDPOINT, headers={"Authorization": f"Bearer {API_KEY}"},
json={"asin": asin, "country": "us"})
r.raise_for_status()
return r.json()["data"]
def summarize(product: dict) -> None:
reviews = product.get("reviews", [])
verified = sum(1 for r in reviews if r.get("verified_purchase"))
print(f"{product.get('title')}")
print(f" rating: {product.get('rating')} over {product.get('reviews_count')} reviews")
print(f" sample: {len(reviews)} records, {verified} verified purchases")
for r in reviews[:3]:
print(f" {r.get('author')} | {r.get('date')}")
if __name__ == "__main__":
summarize(get_review_signal("B09G9FPHY6"))JavaScript Example
const API_KEY = process.env.SCAVIO_API_KEY || "your_scavio_api_key";
const ENDPOINT = "https://api.scavio.dev/api/v1/amazon/product";
async function getReviewSignal(asin) {
const res = await fetch(ENDPOINT, {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ asin, country: "us" })
});
const body = await res.json();
return body.data ?? {};
}
async function main() {
const product = await getReviewSignal("B09G9FPHY6");
const reviews = product.reviews ?? [];
const verified = reviews.filter((r) => r.verified_purchase).length;
console.log(`${product.rating} over ${product.reviews_count} reviews`);
console.log(`sample: ${reviews.length} records, ${verified} verified purchases`);
}
main().catch(console.error);Expected Output
{
"data": {
"asin": "B09G9FPHY6",
"title": "Echo Dot (5th Gen)",
"rating": 4.7,
"reviews_count": 284521,
"reviews": [
{
"id": "R2QX8K1J4M0P7L",
"author": "John D.",
"date": "Reviewed in the United States on February 14, 2026",
"verified_purchase": true
},
{
"id": "R1LC5T9WQ3E2ZB",
"author": "Sarah M.",
"date": "Reviewed in the United States on January 28, 2026",
"verified_purchase": true
}
]
},
"response_time": 2.19,
"credits_used": 1,
"credits_remaining": 6902
}