Guide
Getting started
Six short steps from zero to production-ready product data. Examples are in cURL, Python and JavaScript — pick your language once and every example follows.
1. Request access
Every request is authenticated with your API login and an API key. Accounts are set up on request:
- Request access — tell us what you are building, your expected monthly volume and the marketplaces you need.
- We set up your account — we reply with a quote for your volume (see the list prices), create your account and e-mail you a secure one-time link to your API login and first API key (the key itself is never sent by e-mail).
- Call the API — store the credentials safely and make your first request, as shown below.
2. Store them safely
Keep the key on your server — never in browser or mobile app code. The examples in these docs read the credentials from two environment variables:
export API_LOGIN="your-login"
export API_KEY="sd_live_…your key…"3. Make your first request
The quickest way to see data is live: one request, one result, typically within a few seconds ($0.0040 per request at list price; every response reports the exact cost).
curl --request POST \
--url "https://api.screamingdata.dev/ v1/ amazon/ product/ live" \
--user "$API_LOGIN:$API_KEY" \
--header "Content-Type: application/json" \
--data '[
{
"asin": "B0EXAMPLE1",
"marketplace": "com",
"max_age_minutes": 60
}
]'import os
import requests
response = requests.post(
"https://api.screamingdata.dev/ v1/ amazon/ product/ live",
auth=(os.environ["API_LOGIN"], os.environ["API_KEY"]),
json=[
{
"asin": "B0EXAMPLE1",
"marketplace": "com",
"max_age_minutes": 60,
},
],
timeout=90,
)
data = response.json()
print(data["status_code"], data["status_message"], "cost:", data["cost"])
for task in data["tasks"]:
print(task["id"], task["status_code"], task["status_message"])const auth = Buffer.from(`${process.env.API_LOGIN}:${process.env.API_KEY}`).toString("base64");
const response = await fetch("https://api.screamingdata.dev/ v1/ amazon/ product/ live", {
method: "POST",
headers: {
Authorization: `Basic ${auth}`,
"Content-Type": "application/json",
},
body: JSON.stringify([
{ asin: "B0EXAMPLE1", marketplace: "com", max_age_minutes: 60 },
]),
});
const data = await response.json();
console.log(data.status_code, data.status_message, "cost:", data.cost);
for (const task of data.tasks) {
console.log(task.id, task.status_code, task.status_message);
}4. Read the response
Every endpoint answers with the same envelope. The fields you will use most:
status_code—20000means the request succeeded. Each task has its ownstatus_codetoo; see Status codes.cost— exactly what the request cost in US dollars.tasks[0].result[0]— the product object: title, byline, variants, price, Best Sellers Rank, rating and the label → value pairs ofdetails.
{
"version": "1.0.0",
"status_code": 20000,
"status_message": "Ok.",
"time": "3.8342 sec.",
"cost": 0.004,
"tasks_count": 1,
"tasks_error": 0,
"tasks": [
{
"id": "09241241-1d5e-4c8a-a3f0-9e2b7c6d5a14",
"status_code": 20000,
"status_message": "Ok.",
"time": "3.8120 sec.",
"cost": 0.004,
"result_count": 1,
"path": [
"v1",
"amazon",
"product",
"live"
],
"data": {
"api": "amazon",
"function": "product",
"asin": "B0EXAMPLE1",
"marketplace": "com",
"max_age_minutes": 60
},
"result": [
{
"asin": "B0EXAMPLE1",
"marketplace": "com",
"url": "https://www.amazon.com/ dp/ B0EXAMPLE1",
"observed_at": "2026-09-24T12:41:07Z",
"status": "ok",
"title": "Acme Wireless Noise Cancelling Headphones, Black",
"byline": [
"Acme"
],
"variant": "Black",
"variants": [
{
"name": "Black",
"asin": "B0EXAMPLE1"
},
{
"name": "White",
"asin": "B0EXAMPLE2"
},
{
"name": "Navy Blue",
"asin": "B0EXAMPLE3"
}
],
"price": {
"amount": 59.99,
"currency": "USD"
},
"bsr": {
"rank": 1432,
"category": "Electronics",
"subcategories": [
{
"rank": 12,
"category": "Over-Ear Headphones"
},
{
"rank": 31,
"category": "Noise-Cancelling Headphones"
}
]
},
"rating": 4.5,
"ratings_count": 2318,
"image_url": "https://m.media-amazon.com/ images/ I/ example._AC_SL1500_.jpg",
"details": {
"brand": "Acme",
"color": "Black",
"connectivity_technology": "Wireless",
"date_first_available": "March 4, 2025",
"item_model_number": "AC-WH400",
"item_weight": "8.8 ounces",
"manufacturer": "Acme",
"product_dimensions": "7.3 x 6.5 x 3.1 inches"
},
"parser_version": "2026.09.2"
}
]
}
]
}5. Scale up with batch tasks
For many products, post tasks instead: up to 100 per request at $0.0015 each (list price). Collect results with tasks_ready and task_get, or add a postback_url and let the API deliver them — see Webhooks.
# 1. Post a task and keep its id (jq reads it from the response)
TASK_ID=$(curl -s -u "$API_LOGIN:$API_KEY" \
-H "Content-Type: application/json" \
-d '[{"asin":"B0EXAMPLE1","marketplace":"com","tag":"catalog-sync"}]' \
https://api.screamingdata.dev/ v1/ amazon/ product/ task_post | jq -r '.tasks[0].id')
# 2. Collect the result when it is ready (status_code 40401 = not ready yet)
curl -s -u "$API_LOGIN:$API_KEY" \
https://api.screamingdata.dev/ v1/ amazon/ product/ task_get/$TASK_IDimport os
import time
import requests
API = "https://api.screamingdata.dev/ v1"
AUTH = (os.environ["API_LOGIN"], os.environ["API_KEY"])
# 1. Post a task
posted = requests.post(
f"{API}/amazon/product/task_post",
auth=AUTH,
json=[{"asin": "B0EXAMPLE1", "marketplace": "com", "tag": "catalog-sync"}],
timeout=30,
).json()
first = posted["tasks"][0] if posted["tasks"] else posted
if first["status_code"] != 20100: # e.g. 40200: the balance is too low
raise RuntimeError(f"{first['status_code']} {first['status_message']}")
task_id = first["id"]
# 2. Collect the result when it is ready (40401 = not ready yet), for up to 10 minutes
for _ in range(40):
time.sleep(15)
data = requests.get(f"{API}/amazon/product/task_get/{task_id}", auth=AUTH, timeout=30).json()
task = data["tasks"][0] if data["tasks"] else data
if task["status_code"] != 40401:
break
# 40401: still not ready (collect it later), 40402: no such product, 50301: source
# unavailable — neither of the last two is charged
if task["status_code"] != 20000:
raise RuntimeError(f"{task['status_code']} {task['status_message']}")
product = task["result"][0]
print(product["title"], product["price"], product["bsr"] and product["bsr"]["rank"], product["details"])const API = "https://api.screamingdata.dev/ v1";
const headers = {
Authorization: "Basic " + Buffer.from(`${process.env.API_LOGIN}:${process.env.API_KEY}`).toString("base64"),
"Content-Type": "application/json",
};
// 1. Post a task
const posted = await fetch(`${API}/amazon/product/task_post`, {
method: "POST",
headers,
body: JSON.stringify([{ asin: "B0EXAMPLE1", marketplace: "com", tag: "catalog-sync" }]),
}).then((response) => response.json());
const first = posted.tasks[0] ?? posted;
if (first.status_code !== 20100) throw new Error(`${first.status_code} ${first.status_message}`); // e.g. 40200
const taskId = first.id;
// 2. Collect the result when it is ready (40401 = not ready yet), for up to 10 minutes
let task;
for (let attempt = 0; attempt < 40; attempt += 1) {
await new Promise((resolve) => setTimeout(resolve, 15_000));
const data = await fetch(`${API}/amazon/product/task_get/${taskId}`, { headers }).then((response) => response.json());
task = data.tasks[0] ?? data;
if (task.status_code !== 40401) break;
}
// 40401: still not ready (collect it later), 40402: no such product, 50301: source
// unavailable — neither of the last two is charged
if (task.status_code !== 20000) throw new Error(`${task.status_code} ${task.status_message}`);
const product = task.result[0];
console.log(product.title, product.price, product.bsr?.rank, product.details);6. Monitor products automatically
To track the same products every hour, every 6 hours or every day, add them to monitoring. Fresh observations appear in monitoring/list and in history.
curl --request POST \
--url "https://api.screamingdata.dev/ v1/ amazon/ monitoring/ add" \
--user "$API_LOGIN:$API_KEY" \
--header "Content-Type: application/json" \
--data '[
{
"asin": "B0EXAMPLE1",
"marketplace": "com",
"frequency": "daily",
"tag": "client-42",
"external_user_id": "u_8f3a2c"
},
{
"asin": "B0EXAMPLE2",
"marketplace": "uk",
"frequency": "hourly",
"tag": "launch-watch"
}
]'import os
import requests
response = requests.post(
"https://api.screamingdata.dev/ v1/ amazon/ monitoring/ add",
auth=(os.environ["API_LOGIN"], os.environ["API_KEY"]),
json=[
{
"asin": "B0EXAMPLE1",
"marketplace": "com",
"frequency": "daily",
"tag": "client-42",
"external_user_id": "u_8f3a2c",
},
{
"asin": "B0EXAMPLE2",
"marketplace": "uk",
"frequency": "hourly",
"tag": "launch-watch",
},
],
timeout=30,
)
data = response.json()
print(data["status_code"], data["status_message"], "cost:", data["cost"])
for task in data["tasks"]:
print(task["id"], task["status_code"], task["status_message"])const auth = Buffer.from(`${process.env.API_LOGIN}:${process.env.API_KEY}`).toString("base64");
const response = await fetch("https://api.screamingdata.dev/ v1/ amazon/ monitoring/ add", {
method: "POST",
headers: {
Authorization: `Basic ${auth}`,
"Content-Type": "application/json",
},
body: JSON.stringify([
{
asin: "B0EXAMPLE1",
marketplace: "com",
frequency: "daily",
tag: "client-42",
external_user_id: "u_8f3a2c",
},
{
asin: "B0EXAMPLE2",
marketplace: "uk",
frequency: "hourly",
tag: "launch-watch",
},
]),
});
const data = await response.json();
console.log(data.status_code, data.status_message, "cost:", data.cost);
for (const task of data.tasks) {
console.log(task.id, task.status_code, task.status_message);
}Next steps
- Check your balance and usage with user_data or in the dashboard.
- Read about rate limits before running large batches.
- Browse the full API reference.
Questions?