Recipes
End-to-end pipelines that combine amz commands into real work: price tracking, review mining, competitive scans, and market research.
amz is built to compose. Every command streams the same record types through
the same renderer, so the output of one is the input of the next. These recipes
chain them into the work people actually do with Amazon data. They use jq for
JSON wrangling, but plain sed/awk versions are shown where they are simpler.
Track a price over time
Append a timestamped price row to a CSV on every run, then watch the file:
amz price B084DWG2VQ -o jsonl \
| jq -r '[now|todate, .asin, .price, .currency] | @csv' \
>> price_log.csv
Drop that line in a cron job and you have a price history with no database. To watch a basket, loop a file of ASINs:
while read asin; do amz price "$asin" -o jsonl; done < watchlist.txt \
| jq -r '[now|todate, .asin, .price] | @csv' >> basket_log.csv
Find the cheapest offer for an ASIN
The Buy Box is not always the cheapest. List every offer and sort:
amz offers B084DWG2VQ -o jsonl \
| jq -s 'sort_by(.price) | .[0] | {price, condition, seller_name, is_buybox}'
Or only new, Prime-fulfilled options:
amz offers B084DWG2VQ --condition new --prime -o jsonl | jq -s 'min_by(.price)'
Enrich a chart into full product records
Charts give you ASINs and a thumbnail of data. Fan each one out into a full product record:
amz bestsellers electronics -n 25 -o url \
| sed 's#.*/dp/##; s#/.*##' \
| xargs -I{} amz product {} -o jsonl > top25.jsonl
Now ask questions of the file. Average discount among the top 25:
jq -s 'map(.savings_pct // 0) | add / length' top25.jsonl
The brands that appear most:
jq -r '.brand' top25.jsonl | sort | uniq -c | sort -rn
Mine the reviews of a product
Pull the corpus and skim sentiment without reading a word:
echo "1-star: $(amz reviews B084DWG2VQ --stars 1 -o jsonl | wc -l)"
echo "5-star: $(amz reviews B084DWG2VQ --stars 5 -o jsonl | wc -l)"
The most-helpful complaints, title and vote count:
amz reviews B084DWG2VQ --stars 1 --sort helpful -n 20 -o jsonl \
| jq -r '"\(.helpful_votes)\t\(.title)"'
Reviews that mention a keyword:
amz reviews B084DWG2VQ -o jsonl | jq -r 'select(.text | test("battery"; "i")) | .title'
Compare two products side by side
for a in B084DWG2VQ B09B8V1LZ3; do amz product "$a" -o jsonl; done \
| jq -r '[.asin, .price, .rating, .ratings_count, .rank] | @tsv' \
| column -t
Scan a search for the best-rated value
Search with refinements, then pick the highest-rated card under a price:
amz search "mechanical keyboard" --min-rating 4 --prime -n 100 -o jsonl \
| jq -s 'map(select(.price < 120)) | sort_by(-.rating) | .[0:5]'
Walk a brand's catalog
Turn a brand's featured ASINs into full records:
amz brand anker --featured -o url \
| sed 's#.*/dp/##; s#/.*##' \
| xargs -I{} amz product {} -o jsonl > anker.jsonl
Build a dataset with the local store
For anything beyond a one-shot, let the queue and DuckDB carry the work. Seed a category's bestsellers, drain the queue, then query with SQL. See crawling at scale for the full treatment.
amz bestsellers electronics -n 100 -o url \
| sed 's#.*/dp/##; s#/.*##' \
| amz seed --file -
amz crawl
amz db query "select data->>'brand' brand, count(*) n,
round(avg((data->>'price')::double), 2) avg_price
from products group by brand order by n desc limit 20"
Cross-marketplace price gap
The same ASIN, priced in two storefronts:
for m in us uk de; do
amz price B084DWG2VQ -m "$m" -o jsonl
done | jq -r '[.marketplace // "?", .price, .currency] | @tsv'
Dry-run before a big crawl
See exactly which URLs a run would hit, across marketplaces, without fetching:
amz product B084DWG2VQ -m jp --dry-run
amz bestsellers electronics -m de --dry-run
Keep iterating for free
Every successful fetch is cached, so once you have pulled a page you can refine the shape of the output as much as you like without touching the network:
amz product B084DWG2VQ -o json # first run hits the network
amz product B084DWG2VQ --fields asin,price,ranks # served from cache
amz product B084DWG2VQ --template '{{.title}} is #{{.rank}}'