Install
openclaw skills install @apiclaw/zoodataAPI endpoint reference for the ZooData data platform. Provides the 12 commerce endpoints plus 10 keyword intelligence endpoints (categories, markets, products, competitors, realtime ASIN, AI review analysis, raw reviews, price band, brand, history, keyword detail/trend/extends/search results/market profile/product traffic/competitor keywords, traffic overview/timeline), their inputs/outputs, parameter quirks, Quick Start (auth, base URL), how credits are tracked (meta.creditsConsumed field), and the Local Review Toolkit (Map/Reduce for raw reviews). Use when the user asks about the API itself — which endpoints exist, how to call them, field schemas, parameter quirks, how to authenticate, how credit consumption is reported, or how the Local Review Toolkit works. Use when user asks: what endpoints does ZooData have, how do I call /products/search, fields returned by reviews/analysis, how to check credit usage, how the Local Review Toolkit works, how to get started. Requires ZOODATA_API_KEY.
openclaw skills install @apiclaw/zoodata📋 Live API Reference: Field names and parameters may change. If you encounter field errors, check the latest OpenAPI spec at https://zoodata.ai/api/v1/openapi-spec for current field definitions.
200M+ Amazon products. 22 endpoints. One API key.
export ZOODATA_API_KEY='hms_live_xxx'https://api.zoodata.ai/openapi/v2 — all POST with JSON bodyAuthorization: Bearer YOUR_API_KEYhttps://api.zoodata.ai (Bearer ZOODATA_API_KEY). Setting ZOODATA_BASE_URL to an untrusted host (anything other than api.zoodata.ai / *.zoodata.ai / localhost) makes the CLI refuse the request and withhold the key — the Bearer token is never sent to an untrusted host.{skill_base_dir}/scripts/zoodata.py (Python 3, stdlib-only). The shared CLI exposes ALL ZooData endpoints as subcommands; this skill's workflows use: all subcommands — this is the data-layer reference skill, so the full CLI surface is the declared surface. Do not invoke unrelated subcommands for this skill's tasks.~/.zoodata/config.json; the Local Review Toolkit uses a temporary /tmp/review_<ASIN>_<timestamp>/ working dir during the review fallback.categoryPath first via categories endpointsampleAvgMonthlyRevenue directly. NEVER calculate avgPrice × totalSales (overestimates 30-70%)monthlySalesFloor (lower bound). Fallback: 300,000 / BSR^0.65, tag as 🔍sampleOpportunityIndex, sampleTop10BrandSalesRate — never reinventrealtime/product → ratingBreakdown (star distribution only, no themes)realtime/reviews (raw text, up to 100) + local Map/Reduce via the
Local Review Toolkit below — see "Local Review Toolkit" sectionkeyword (not categoryPath) — cross-validate returned productsmode is CLI-local, NOT an API parameter → zoodata.py expands --mode client-side into the filter sets in PRODUCT_MODES ({skill_base_dir}/scripts/zoodata.py, 13 presets) before the request; sending mode raw → 422--sales-min → monthlySalesMin; --ratings-max (review count) → ratingCountMax, not ratingMax (a different valid field — max star rating — that returns wrong results silently, no 422). Pass categoryPath as a JSON array (["Electronics"]), never a string. Unknown fields (salesMin, ratingsMax, …) → 422BEFORE calling any endpoint, verify credentials are configured. The reliable check is python {skill_base_dir}/scripts/zoodata.py check — credentials-only by default, no endpoint calls and no credit usage; exits non-zero if no key is found in env vars OR config files. A [ -z "$ZOODATA_API_KEY" ] test alone is NOT sufficient — a user may have only ~/.zoodata/config.json set.
When no key is found through any mechanism:
zoodata.py (you'll just get the same credential error and burn tokens).ZOODATA_API_KEY is not set — I need this to run the analysis."export ZOODATA_API_KEY='hms_live_xxx' (session only)mkdir -p ~/.zoodata && echo '{"api_key":"hms_live_xxx"}' > ~/.zoodata/config.json (persistent)When zoodata.py returns {"code": 401, "message": "API Key invalid or expired"}:
ZOODATA_API_KEY in use was rejected (likely invalid, revoked, or expired)When zoodata.py returns {"code": 402, "message": "API quota exhausted or subscription expired"}:
| # | Endpoint | Purpose | Key Output |
|---|---|---|---|
| 1 | categories | Browse/search category tree | categoryPath, productCount |
| 2 | markets/search | Market-level metrics | sampleAvgMonthlySales, sampleAvgPrice, topSalesRate, sampleNewSkuRate |
| 3 | products/search | Product search (20+ filter fields) | asin, price, monthlySalesFloor, rating, ratingCount, fbaFee |
| 4 | products/competitors | Competitor discovery | same fields as products/search |
| 5 | realtime/product | Live ASIN detail | rating, features, bestsellersRank[], buyboxWinner.price, variants |
| 6 | reviews/analysis | AI review insights (11 dims) | sentimentDistribution, consumerInsights, topKeywords |
| 7 | realtime/reviews | Live raw review text (cursor paginated, max 100) | reviews[], nextCursor — feeds Local Review Toolkit |
| 8 | products/price-band-overview | Price band summary | hottestBand, bestOpportunityBand, sampleOpportunityIndex |
| 9 | products/price-band-detail | Full 5-band distribution | priceBands[] with sales, brands, ratings per band |
| 10 | products/brand-overview | Brand concentration | sampleTop10BrandSalesRate (CR10), sampleBrandCount |
| 11 | products/brand-detail | Per-brand breakdown | brands[] with sales, revenue, sampleProducts |
| 12 | products/history | Time series (single ASIN per call) | timestamps[], price[], bsr[], monthlySalesFloor[], rating[], ratingCount[], sellerCount[], title/imageUrl/bestSeller/newRelease/aPlus/inventoryStatus changelogs |
| 13 | /openapi/v2/keywords/detail | Keyword summary from the nearest available weekly snapshot | estimateSearchCountWeekly, abaRank, marketCharacteristics, adCount; may return data: null |
| 14 | /openapi/v2/keywords/market-profile | Pre-release multidimensional weekly keyword profile | demand scale, Top3 concentration, ad activity, organic-entry difficulty, saturation, brand structure, organic benchmark, coverage |
| 15 | /openapi/v2/keywords/trend | Weekly keyword time series | estimateSearchCount, abaRank, rankChangeCount, periodStartDate, periodEndDate |
| 15b | /openapi/v2/keywords/trend-profile | Server-calculated trend profile over fixed weekly windows | trend shape, volatility, normalized slope, direction consistency, ABA-rank evidence |
| 16 | /openapi/v2/keywords/extends | Keyword expansion / long-tail discovery | related keywords ranked by relevanceScore / estimateSearchCount; may return empty array |
| 17 | /openapi/v2/keywords/search-results | Daily keyword SERP snapshot | asin, exploreType, absolutePosition, estimateImpressionPoint, listing fields |
| 18 | /openapi/v2/keywords/competitor-product-keywords | Keyword set where an ASIN appears as a competitor | keyword, avgPosition, keywordEstimateSearchCount, trafficShare |
| 19 | /openapi/v2/keywords/product-traffic-terms | Traffic-driving keywords for an ASIN | same live response shape as competitor-product-keywords |
| 20 | /openapi/v2/keywords/product-traffic-terms-overview | Weekly ASIN all-keyword traffic-change overview | current vs previous-period placement-level impression points, ORG first-3-page keyword entries/exits |
| 21 | /openapi/v2/keywords/product-traffic-terms-timeline | ASIN + keyword daily timeline | position/impression points, listing snapshot, keyword weekly metrics, ad activity |
topN, listingAge, newProductPeriod are strings ("10" not 10).data as an array — use .data[0] for the first record. But some commands may return non-array payloads inside data, so inspect the actual response shape before indexing.ratingCount not reviewCount everywherebsr (int) in products vs bestsellersRank (array) in realtimebuyboxWinner.price — NOT top-level price in realtimerealtime/product does NOT return: monthlySalesFloor, fbaFee, sellerCountrealtime/product cold-start: first call for an uncached ASIN may return success: true with an EMPTY data (asin: "") while the live fetch warms up — retry once after a few seconds before concluding "no data" (still billed 1 credit per call)reviewCountMin/Max filters currently broken (API-56)reviews/analysis may 500 for certain ASINs (API-58) — retry different ASINcategories uses categoryKeyword (not keyword) and parentCategoryPath (not parentCategoryName)reviews/analysis: mode required ("asin"/"category"), use asins (plural array) not asinrealtime/reviews: returns 10 reviews/page fixed (no pageSize param); 1 credit/page; cursor-paginated; hard cap = 100 reviews (10 pages); supports marketplace US/UK onlykeywords/detail resolves the input date to the nearest available weekly snapshot at or before that date, and may legitimately return data: null even with success: truekeywords/market-profile is pre-release on localhost as of 2026-07-14 and is not yet published; it accepts one of keyword / keywords[] (max 20), requires date, supports weekly granularity only, and returns input-ordered data.items[]keywords/trend-profile is available on localhost and not yet published; it accepts one of keyword / keywords[] (max 20), requires date and 1–4 unique windowPeriods selected from 4/8/12/26, and supports weekly granularity onlykeywords/extends also resolves the input date to the nearest available weekly snapshot, requires query (not keyword), supports queryType = phrase or fuzzy, and may legitimately return data: []keywords/search-results, keywords/competitor-product-keywords, and keywords/product-traffic-terms use daily observations over a sliding ~7-day window, not a long-retention historical storekeyword or query, use the Amazon search query / keyword phrase being analyzeddate or dateTo, prefer T-1 or earlier and avoid the current date unless the user explicitly asks for today's lookupkeywords/search-results requires date + keyword; exploreTypes values are ORG, SP, SB, SBV, SPRkeywords/competitor-product-keywords and keywords/product-traffic-terms require date + asin; both currently return the same live item shape, including trafficSharekeywords/product-traffic-terms-overview requires date + asin; it returns the latest weekly overview of all keyword impression traffic changes under that ASIN at or before the date, compared with the previous periodkeywords/product-traffic-terms-timeline requires asin + exact keyword + dateFrom + dateTo; the date range cannot exceed 60 dayskeywords/search-results is the default source for explaining what products currently appear on a keyword SERP because it already returns listing-level product fieldsproducts/search is a broader ZooData product-database query and must not be presented as Amazon live keyword SERP orderingThese nine endpoints fill the gap between raw catalog data and search-demand/search-visibility intelligence.
Keyword value boundary:
品牌分析 -> 搜索分析 -> 搜索查询绩效 -> 品牌视图; English Seller Central path Brand Analytics -> Search Analytics -> Search Query Performance -> Brand View[Search Funnel - Impressions](https://sellercentral.amazon.com/brand-analytics/metric-glossary?linkedFrom=query-performance-brand-report-table-qp-impressions-group) -> Brand Count / 搜索漏斗-展示次数 -> 品牌数量, then provide a screenshot; alternatively, download the CSV and provide it for model analysis/openapi/v2/keywords/detailkeyword, date, optional marketplacedate to the nearest available weekly snapshot at or before that datedate; avoid current-date lookup unless explicitly requesteddata is an object or null (not an array)estimateSearchCountWeekly, abaRank, abaTop3ClickShareRate,
abaTop3ConversionShareRate, marketCharacteristics, totalSkuCnt, brandCount,
organicSkuCount, adCampaignCount, adCountkeyword="yoga mat" and several June 2026 dates, the endpoint returned
success: true with data: null/openapi/v2/keywords/market-profile (metric layer, localhost pre-release)http://localhost:8080 as of 2026-07-14; not yet published to productionkeyword or keywords[] (1–20), required date, optional marketplace, granularity=weekdata.context + data.items[], preserving request orderrequestedDate, resolvedDate, dataWindow.currentPeriod, scoringSpec, marketplace/site/granularityidentity, status=available|not_found, marketProfile, unavailableReasonmarketProfile dimensions: marketCharacteristics, demandScale, top3Concentration, adActivity, top20OrganicEntryDifficulty, supplySaturation, brandStructure, organicProductBenchmarkcontext.scoringSpec (id, version, scoreType, scoreRange, referenceScope). Scored dimensions expose supported, calculationStatus, unsupportedReason, level, interpretation, and levelEvidence.score.{value,direction}. There is no aggregate coverage object.marketCharacteristics.volatility and marketCharacteristics.annualSeasonality are independent evidence objects. Do not collapse their classifications, let one override the other, or invent peak periods from an empty list.status=not_found, marketProfile=null, unavailableReason=keyword_not_observed, and zero consumed credits; resolved context and scoringSpec may be nullnot_found; do not automatically fan out all subjects into single calls.keywords/detail for source snapshot fields, metric-layer keywords/market-profile for stable deterministic profile objects, and the Agent + skill layer for evidence composition, confidence, explanations, limitations, and actions/openapi/v2/keywords/trendkeyword, dateFrom, dateTo, optional marketplacedateTo; avoid current-date lookup unless explicitly requesteddata is an arrayobservedAt, periodStartDate, periodEndDate,
estimateSearchCount, estimateSearchChangeCount, estimateSearchChangeRate, abaRank,
prevAbaRank, prevEstimateSearchCount, rankChangeCount/openapi/v2/keywords/trend-profile (metric layer, localhost pre-release)keyword / keywords[] (1–20), required date, required unique windowPeriods[] selected from 4/8/12/26, optional marketplace, granularity=weekdata.context + data.items[].rows[]; every requested window returns one row with rowContext, status=available|unavailable|not_found, unavailableReason, and trendProfilesearchDemand and abaRank dimensions with trend, trendPattern, and {value,direction} entries under trendEvidencekeywords/trend for trend-shape and volatility judgments. Descend only for required weekly points or fields omitted from the profile./openapi/v2/keywords/extendsquery, date, optional marketplace, page, pageSize, queryType, sortBy, sortOrderquery, not keyword; queryType supports phrase and fuzzydate to the nearest available weekly snapshot at or before that datedate; avoid current-date lookup unless explicitly requesteddata is an arrayterm, seedKeyword, relevanceScore, estimateSearchCountWeekly,
abaRank, marketCharacteristics, brandCount, organicSkuCount, adCount,
periodStartDate, periodEndDate, observedAtquery="yoga mat" returned data: [] for both
queryType="phrase" and queryType="fuzzy"/openapi/v2/keywords/search-resultskeyword, date, optional marketplace, page, pageSize, exploreTypes, sortBy, sortOrderdate; avoid current-date lookup unless explicitly requesteddata is an arrayexploreType, absolutePosition, pageIndex,
pagePosition, asin, title, brand, price, currency, link, imageLink, rating,
ratingCount, recentSales, hasVideo, estimateImpressionPoint,
keywordTotalEstimateImpressionPointproducts/search when the question is about observed keyword SERP composition or ordering/openapi/v2/keywords/competitor-product-keywordsasin, date, optional marketplace, page, pageSize, exploreTypes,
keywordContains, sortBy, sortOrderdate; avoid current-date lookup unless explicitly requesteddata is an arrayexploreType, absolutePosition, pageIndex,
pagePosition, asin, keyword, estimateImpressionPoint, asinTotalEstimateImpressionPoint,
avgPosition, daysCoverageRate, observationCount, keywordEstimateSearchCount,
keywordEstimateSearchGrowthCount, keywordEstimateSearchCountChangeRate, keywordAbaRank,
keywordAbaRankChangeCount, trafficShare/openapi/v2/keywords/product-traffic-termskeywords/competitor-product-keywordsdate; avoid current-date lookup unless explicitly requesteddata is an arrayexploreType, absolutePosition, pageIndex,
pagePosition, asin, keyword, estimateImpressionPoint, asinTotalEstimateImpressionPoint,
avgPosition, daysCoverageRate, observationCount, keywordEstimateSearchCount,
keywordEstimateSearchGrowthCount, keywordEstimateSearchCountChangeRate, keywordAbaRank,
keywordAbaRankChangeCount, trafficSharekeywords/competitor-product-keywords
field-for-field; keep the semantic distinction in output wording rather than assuming a unique schema/openapi/v2/keywords/product-traffic-terms-overviewasin, date, optional marketplacedate; avoid current-date lookup unless explicitly requesteddata is an object or nullperiodStartDate, periodEndDate, asin, site,
organicImpressionPoint, sponsoredProductImpressionPoint, sponsoredBrandImpressionPoint,
sponsoredBrandVideoImpressionPoint, sponsoredRecommendImpressionPoint,
organicImpressionPointPrev, sponsoredProductImpressionPointPrev,
sponsoredBrandImpressionPointPrev, sponsoredBrandVideoImpressionPointPrev,
sponsoredRecommendImpressionPointPrev, first3PagesNewOrganicKeywords,
first3PagesLostOrganicKeywords*Prev fields are previous-period baselines for the matching current impression-point fieldsfirst3PagesNewOrganicKeywords and first3PagesLostOrganicKeywords are arrays of objects with
keyword, pageIndex, and pagePositionfirst3PagesNewOrganicKeywords lists keywords newly entering ORG first three pages; first3PagesLostOrganicKeywords
lists keywords that dropped out of ORG first three pagesopenapi_v2_product_traffic_terms_overview on
http://localhost:8080/mcp, asin="B01CGLCGRA", date="2026-06-29", marketplace="US"/openapi/v2/keywords/product-traffic-terms-timelineasin, exact keyword, dateFrom, dateTo, optional marketplace, page, pageSize,
sortBy, sortOrderdateTo; avoid current-date lookup unless explicitly requesteddata is an arraykeyword* fields are keyword traffic-forecast dependency data for the provided keyword's corresponding metric period, indicated by keywordPeriodStartDate / keywordPeriodEndDatelatest* fields are the ASIN's latest product/listing/rank snapshot on the specified dateavg* fields, ad-activity fields, and placement observations are rolling metrics for the most recent 7 days ending at the given datelatestPrice), BSR (latestSmallCategoryBsr, latestBigCategoryBsr),
sales (latestMonthlySaleCnt), rating (latestRatingAmt, latestRatingCnt), traffic estimate
(impression-point fields plus avgOrganicObservation / avgAdObservation), and listing events
(latestTitle, latestMainImageLink)date, site, asin, keyword, listing snapshot fields
such as latestTitle, latestPrice, latestCurrency, latestLink, latestMainImageLink,
latestBrandName, latestMonthlySaleCnt, latestRatingAmt, latestRatingCnt,
latestSmallCategoryName, latestSmallCategoryBsr, latestBigCategoryName,
latestBigCategoryBsr, latestProductHasVideo; placement fields such as exploreTypes,
exploreRecommendTypes, organicImpressionPoint, sponsoredProductImpressionPoint,
sponsoredBrandImpressionPoint, sponsoredBrandVideoImpressionPoint,
sponsoredRecommendImpressionPoint, latestOrganicPosition, latestOrganicPageIndex,
latestOrganicPagePosition, latestOrganicObservedAt, latestAdPosition,
latestAdPageIndex, latestAdPagePosition, latestAdObservedAt, avgOrganicObservation,
avgAdObservation; keyword snapshot fields such as keywordPeriodStartDate,
keywordPeriodEndDate, keywordEstimateSearchCnt, keywordEstimateSearchGrowthCnt,
keywordAbaRank, keywordAbaRankGrowthCnt, keywordAbaTopClickShareRate,
keywordAbaTopConversionShareRate, keywordTitleDensity, keywordTotalSkuCnt,
keywordObservedSkuCnt, keywordOrganicSkuCnt, keywordSponsoredProductSkuCnt,
keywordSponsoredBrandSkuCnt, keywordSponsoredBrandVideoSkuCnt,
keywordSponsoredRecommendSkuCnt; ad activity fields adActiveObservationCount,
adActiveDayCoverageRate, adCampaignCnt, adCntopenapi_v2_product_traffic_terms_timeline on
http://localhost:8080/mcp, asin="B01CGLCGRA", keyword="yoga mat",
dateFrom="2026-06-23", dateTo="2026-06-29", marketplace="US"When /reviews/analysis lacks aggregation (ASIN has <50 reviews or no daily snapshot),
fall back to live raw reviews + your own LLM. The toolkit does NOT call any external
LLM — you (the calling skill's LLM) perform the Map/Reduce steps.
Workflow:
# 1. Fetch raw reviews (up to 100, cursor-paginated, ~60s, 10 credits at full)
zoodata.py reviews-raw --asin B0XXXXXXXX [--marketplace US] [--max-pages 10]
# 2. For EACH review, render the per-review Map prompt
zoodata.py review-tag-prompt --review '<single review JSON>' \
[--product-title "..."] [--product-category "..."]
# → Your LLM produces a JSON object with sentiment + 11 dimension arrays
# (mentioned_scenarios, mentioned_issues, mentioned_positives, mentioned_improvements,
# mentioned_buying_factors, mentioned_pain_points, user_profiles, mentioned_usage_times,
# mentioned_usage_locations, mentioned_behaviors, keywords)
# Suggested map parallelism: ~20 concurrent if your LLM supports it
# 3. Collect candidate phrases per dimension. For EACH dimension render the Reduce prompt
zoodata.py review-reduce-prompt --label-type positives \
--candidates '["comfortable","comfy","very comfortable",...]'
# → Your LLM produces {clusters: [{canonical, members}, ...]}
# Suggested chunk size for `keywords` dim when >150 candidates: 150 per call
# 4. Aggregate into reviews/analysis-compatible consumerInsights
zoodata.py review-aggregate --reviews raw.json --tagged tags.json --clusters clusters.json
# → Output shape matches /reviews/analysis: reviewCount, avgRating,
# sentimentDistribution, consumerInsights[], topKeywords[]
When to use the toolkit instead of reviews/analysis:
reviews/analysis returns sparse consumerInsights (missing dimensions)| Data | markets | products/competitors | realtime/product | reviews/analysis | realtime/reviews | price-band | brand | history |
|---|---|---|---|---|---|---|---|---|
| Sales | sampleAvgMonthlySales | monthlySalesFloor | ❌ | ❌ | ❌ | sampleSalesRate | sampleGroupMonthlySales | monthlySalesFloor[] |
| Price | sampleAvgPrice | price | buyboxWinner.price | ❌ | ❌ | bandMin/MaxPrice | sampleAvgPrice | price[] |
| BSR | sampleAvgBsr | bsr (int) | bestsellersRank[] | ❌ | ❌ | ❌ | ❌ | bsr[] |
| Rating | sampleAvgRating | rating | rating | avgRating | rating (per review) | sampleAvgRating | sampleAvgRating | rating[] |
| Reviews | sampleAvgReviewCount | ratingCount | ratingCount | reviewCount | reviews[] (raw text, max 100) | ❌ | sampleAvgRatingCount | ratingCount[] |
| Insights | ❌ | ❌ | ❌ | ✅ consumerInsights | ❌ (raw only — feeds Local Review Toolkit) | ❌ | ❌ | ❌ |
| Concentration | topSalesRate | ❌ | ❌ | ❌ | ❌ | sampleTop3BrandSalesRate | CR10 | ❌ |
| Opportunity | ❌ | ❌ | ❌ | ❌ | ❌ | sampleOpportunityIndex | ❌ | ❌ |
Strategy recommendations and subjective conclusions are NEVER 📊. Extreme growth (>200%) = 💡 only.
monthlySalesFloor) = lower-bound estimatemeta.creditsConsumed