Base URL: https://amzapi.tagxdata.com
The API has two kinds of endpoints:
/pdp) — synchronous Send a product URL, get the parsed product JSON back in the same response./scrape + /result) — asynchronous Submit a job, receive a request_id, then poll for the result when it is ready.| Endpoint | Method | Type | Purpose | Cost |
|---|---|---|---|---|
/credits | GET | — | Check remaining credit balance | Free |
/pdp | POST | sync | Get product details from a product URL | $0.10 |
/scrape | POST | async | Submit a reviews scrape job | from $0.02 |
/result/{request_id} | GET | async | Fetch the result of a submitted job | Free |
Every request must include your API key in the x-api-key header.
x-api-key: your_api_key_here
Returns the remaining credit balance for the authenticated user. This endpoint is free.
curl -X GET "https://amzapi.tagxdata.com/credits" \ -H "x-api-key: your_api_key_here"
import requests
resp = requests.get(
"https://amzapi.tagxdata.com/credits",
headers={"x-api-key": "your_api_key_here"},
)
print(resp.json()) # {'credits': 10.0}
{
"credits": 10.0
}
Fetches a product page and returns the parsed product details as JSON in the same response — there is no polling. The URL is validated first: it must be a valid product URL from a supported marketplace. Invalid or non-product URLs are rejected before any credits are charged.
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Full product URL. It must contain a product ID (for example /dp/PRODUCTID). |
Each successful call costs $0.10 (or your account's custom PDP rate). If the page cannot be fetched, the charge is automatically refunded.
curl -X POST "https://amzapi.tagxdata.com/pdp" \
-H "x-api-key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.example.com/dp/PRODUCTID"
}'
import requests
resp = requests.post(
"https://amzapi.tagxdata.com/pdp",
headers={
"x-api-key": "your_api_key_here",
"Content-Type": "application/json",
},
json={"url": "https://www.example.com/dp/PRODUCTID"},
)
result = resp.json()
product = result["data"]
print(product["title"], product["price"]["current"])
The parsed product is returned under data:
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"cost": 0.10,
"data": {
"asin": "PRODUCTID0",
"title": "Example Product Title - Variant, Size, Colour",
"price": { "current": "1900", "list_price": null },
"images": [ "https://images.example.com/i/product-1_large.jpg", "..." ],
"description": "",
"features": [ "Key selling point one ...", "Key selling point two ...", "..." ],
"brand": "Example Brand",
"brand_url": "https://www.example.com/stores/ExampleBrand/page/...",
"category": [],
"rating": {
"average": "4.5",
"count": "78",
"breakdown": { "five_star": "...", "four_star": "...", "three_star": "...", "two_star": "...", "one_star": "..." }
},
"seller": {},
"variants": [ "16.9 Fl Oz (Pack of 1)", "33.8 Fl Oz (Pack of 1)" ],
"additional_details": {},
"coupon": null,
"coupon_details": null,
"prime_flag": "Yes",
"subscribe_and_save": "YES",
"video": [],
"feature_bullets_count": 5,
"count_of_images": 10,
"amazons_choice_flag": "YES",
"best_seller_flag": "NO",
"climate_pledge_friendly": "YES",
"small_business_badge": "NO"
}
}
| Field | Description |
|---|---|
asin | The product's 10-character identifier. |
price.current | Current price as digits with no separators, e.g. "1900" = 19.00 in the marketplace currency. null if unavailable. |
price.list_price | Original / struck-through price including its currency symbol (e.g. "$24.99"), or null. |
images / count_of_images | Main gallery image URLs and their count. |
features / feature_bullets_count | "About this item" bullet points and their count. |
rating | average stars, total count, and per-star breakdown. The breakdown may be empty when the marketplace loads it lazily for low-review products. |
variants | Available variant labels (size, color, style, ...). |
additional_details | Key/value pairs from the product information / specification table. |
| badge flags | Program / eligibility flags such as fast-shipping, subscription, editor's-choice, best-seller, eco-friendly and small-business badges. Each is returned as "Yes"/"YES" or "No"/"NO". |
A field that is not present on a given product is returned empty (null, [], or {}) rather than omitted, so the response shape is always the same.
Scraping reviews can take a while, so it runs as a background job in two steps:
POST /scrape with the product URL. You immediately get back a request_id. Credits are charged at submission.GET /result/{request_id}. While the job runs you receive HTTP 202 (still processing); once finished you receive HTTP 200 with the review data./result every few seconds until you get a 200. If the job fails during processing you receive a 403 and your credits are automatically refunded.
Submits a reviews-scraping job for a product URL and returns a request_id.
| Field | Type | Default | Description |
|---|---|---|---|
url | string | — | Required. Full product URL. |
all_reviews | boolean | true | true = scrape the full review history (all pages). false = a lighter, single-batch scrape. Ignored when pages is set. |
reviewer_type | string | "all_reviews" | "all_reviews" = every review. "avp_only_reviews" = verified purchase reviews only. |
sort_by | string | "recent" | "recent" = newest first. "" (empty) = the marketplace's "top reviews" ordering. |
pages | integer | — | Optional. Scrape an exact number of review pages (1–9). When provided, it forces the paged mode and overrides all_reviews. |
all_reviews field (boolean) controls how many reviews are scraped. The value "all_reviews" for the reviewer_type field controls which reviewers are included. They are unrelated.
| Mode | Cost |
|---|---|
Full history (all_reviews: true) | $0.50 (or your custom rate) |
Light scrape (all_reviews: false) | $0.10 (or your custom rate) |
Paged (pages: N) | $0.02 for the first page + $0.01 per additional page (e.g. 3 pages = $0.04) |
curl -X POST "https://amzapi.tagxdata.com/scrape" \
-H "x-api-key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.example.com/dp/PRODUCTID"
}'
curl -X POST "https://amzapi.tagxdata.com/scrape" \
-H "x-api-key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.example.com/dp/PRODUCTID",
"reviewer_type": "avp_only_reviews",
"sort_by": ""
}'
curl -X POST "https://amzapi.tagxdata.com/scrape" \
-H "x-api-key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.example.com/dp/PRODUCTID",
"pages": 3
}'
Cost: $0.02 + 2 × $0.01 = $0.04
import requests, time
BASE = "https://amzapi.tagxdata.com"
headers = {"x-api-key": "your_api_key_here", "Content-Type": "application/json"}
# 1) Submit the job
resp = requests.post(f"{BASE}/scrape", headers=headers, json={
"url": "https://www.example.com/dp/PRODUCTID",
"all_reviews": True,
"reviewer_type": "all_reviews",
"sort_by": "recent",
})
request_id = resp.json()["request_id"]
print("Submitted:", request_id)
# 2) Poll until ready (202 = still processing, 200 = done)
while True:
r = requests.get(f"{BASE}/result/{request_id}", headers=headers)
if r.status_code == 202:
time.sleep(5)
continue
r.raise_for_status()
reviews = r.json()
break
print(reviews)
{
"message": "Request accepted",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
Fetches the result of a previously submitted /scrape job. Poll this until it returns 200.
| Code | Meaning |
|---|---|
200 | Done — the body contains the scraped review data. |
202 | Still processing — wait and poll again. |
403 | The job failed during processing. Credits were refunded. |
404 | No job found for that request_id. |
curl -X GET "https://amzapi.tagxdata.com/result/550e8400-e29b-41d4-a716-446655440000" \ -H "x-api-key: your_api_key_here"
import requests
request_id = "550e8400-e29b-41d4-a716-446655440000"
r = requests.get(
f"https://amzapi.tagxdata.com/result/{request_id}",
headers={"x-api-key": "your_api_key_here"},
)
if r.status_code == 202:
print("Still processing, try again shortly.")
elif r.status_code == 200:
print(r.json()) # review data
The body contains the scraped reviews for the product (structure depends on the request parameters).
Errors use standard HTTP status codes with a JSON body:
{
"detail": "Error message description"
}
| Code | Meaning |
|---|---|
200 | OK — successful request with data. |
202 | Accepted — job is still processing (poll again). |
400 | Bad Request — invalid parameters (e.g. not a valid product URL, or pages outside 1–9). |
401 | Unauthorized — invalid or missing API key. |
402 | Payment Required — not enough credits. |
403 | Forbidden — a reviews job failed during processing (credits refunded). |
404 | Not Found — request_id does not exist. |
502 | Bad Gateway — the product page could not be fetched from the source (e.g. blocked). The /pdp charge is refunded. |
500 | Internal Server Error — unexpected error. |