Prepare a small input list
You need Node.js 20 or newer and an API key. Clone the runnable documentation examples and saveurls.json in that checkout:
urls.json
Process one product at a time
Run the example with a stable run ID:catalog-review-001:1. The script waits for a product’s cached or queued extraction to complete before submitting the next. Its public client.mjs helper handles 200 and 202, polls at most 20 times per product at three-second intervals, rejects redirects and sets per-request timeouts.
multiple-product-urls.mjs
results.json after that item finishes. The checkpoint contains the input list and logical operation IDs, never your API key. Read product media from each item’s result.data.media, source details from result.data.source and limitations from result.data.warnings.
Resume without creating duplicate charges
If the script stops, keep the same input list, order andAMZDOWNLOADER_RUN_ID when rerunning it. Completed requests replay with their original idempotency keys and do not charge another credit. A pending request can return its existing job ID. If the helper prints a job ID when its polling budget expires, you can inspect that job directly rather than restart the loop.
Changing an input while keeping its old operation ID can return 409. Use a new run ID for a genuinely new list or changed request settings. Do not automatically start a fresh run after a timeout. The script stops on an error rather than silently retrying a charged operation.
Budget credits and account limits
For two new successful extractions, budget two credits. Each successful product retrieval costs one credit even when it returns cached media. Polling, owned result reads and identical idempotent replays add no credits. This script does not convert videos; adding successful video conversions would cost one extra credit each. Current account limits are 60 requests per minute and three concurrent operations across API keys. Sequential processing keeps this example to one operation at a time, but other applications using the account still share those limits. Honor a returnedRetry-After and investigate 402, 409, 429 or source errors before resuming. A local polling limit does not cancel a server job.
Use a fresh cache read only when you intend a separate media retrieval. GET /products/{asin}/media does not start extraction on a miss. For freshness and coverage, retain fetchedAt, marketplace and warnings for each item. See usage, cache and the API overview.