ZooData — Commerce Data Infrastructure for AI Agents
API endpoint reference for ZooData's Amazon commerce and keyword-intelligence surfaces, including request/response schemas, parameter quirks, authentication, credit metadata, product-traffic structure and trend APIs, and the Local Review Toolkit.
How to use it
Claude Code
- Run the line below. It pulls the whole folder into
~/.claude/skills/zoodata, including the files SKILL.md points to. - Describe your job in plain words. Claude Code follows the skill from there.
npx degit SerendipityOneInc/ZooData-Skills/zoodata#main ~/.claude/skills/zoodataFor one project only, change the path to .claude/skills/zoodata. This skill also uses zoodata.py, raw.json, tags.json, clusters.json — copying SKILL.md alone won't be enough. See the folder on GitHub.
Claude (web or desktop app)
- On this page open ⋯ → Download .md.
- Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
- Pick the file and Save. Claude shows the name and description and runs a security scan.
- Check the skill is switched on.
- Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
- ChatGPT: make a Project and paste it into Instructions.
- Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
- Check which app you pasted it into — the steps above name the right one.
- Some skills need the paid tier of Claude or ChatGPT.
Paste into Claude, ChatGPT or Cursor.
Source of ZooData — Commerce Data Infrastructure for AI Agents
Show the full text335 lines
| name | description | metadata |
|---|---|---|
| zoodata | > API endpoint reference for ZooData's Amazon commerce and keyword-intelligence surfaces, including request/response schemas, parameter quirks, authentication, credit metadata, product-traffic structure and trend APIs, and the Local Review Toolkit. Use when the user asks about the API itself: which endpoints exist, how to call them (e.g. /products/search), field schemas returned by an endpoint, parameter quirks, how to authenticate, how credit consumption is reported, how to get started, or how the Local Review Toolkit works. Requires ZOODATA_API_KEY. | version: "1.3.0 author: SerendipityOneInc homepage: https://github.com/SerendipityOneInc/ZooData-Skills openclaw: {"requires": {"env": ["ZOODATA_API_KEY"]}, "primaryEnv": "ZOODATA_API_KEY"} |
📋 Live API Reference: Field names and parameters may change. For MCP calls, refresh and inspect the current ZooData MCP
inputSchema; for direct HTTP calls, also consult the OpenAPI spec at https://zoodata.ai/api/v1/openapi-spec. Keyword compatibility field: all eleven current keyword and product-traffic request schemas retaingranularity, but the only supported value isweek. The bundled CLI always sendsgranularity=week. Never sendday,month,lately_day, or legacylookbackDays; use the weekly period boundaries returned by the service.
ZooData — Commerce Data Infrastructure for AI Agents
200M+ Amazon products. 25 Amazon and keyword-intelligence endpoints. One API key.
Quick Start
- Get key: zoodata.ai/api-keys (1,000 free credits)
export ZOODATA_API_KEY='hms_live_xxx'- Base URL:
https://api.zoodata.ai/openapi/v2— all POST with JSON body - Auth:
Authorization: Bearer YOUR_API_KEY - New keys need 3-5s to activate. If 403, wait and retry.
Capabilities & Data Flow
- Network: only
https://api.zoodata.ai(BearerZOODATA_API_KEY). SettingZOODATA_BASE_URLto an untrusted host (anything other thanapi.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. - Execution: bundled shared ZooData CLI
{skill_base_dir}/scripts/zoodata.py(Python 3, stdlib-only). This data-layer reference skill allows the complete literal subcommand surface exposed by the bundled client's current top-level help. - Local files: none by default; reads the optional credential store
~/.zoodata/config.json; the Local Review Toolkit uses a private temporary working dir (created withmktemp -d, removed when the fallback completes) during the review fallback. - Sent to the API: keywords, category paths, ASINs, marketplace/date and numeric filter values only. Never sent: budget, experience level, risk tolerance, or any other user-profile text — profile inputs map client-side to numeric filters.
- Credits: every API call consumes account credits. For broad or ambiguous requests, state the estimated credit cost and confirm with the user before running multi-call scans.
Shared CLI contract
Before selecting or invoking a bundled CLI command, read and apply references/cli-contract.md; reapply it after every result. It is the local source of truth for invocation, command identity, execution-environment permission handling, composite reuse, exit-status handling, authoritative transport status, retries, terminal interface failures, and partial results.
For market endpoint schemas and quirks, load references/openapi-reference.md § 2; that file owns their request and response contracts. references/reference.md is a summary index and links to the owner instead of restating the market schemas.
Local Interface Failure Output
For this API-reference skill, a terminal interface failure must produce one concise localized notice stating that the ZooData API lookup could not be completed, followed by the succeeded and failed endpoint identifiers. Do not continue into endpoint guidance, schema interpretation, or another API call. Do not expose control tokens or internal retry logs unless the user requests diagnostics.
⚠️ Critical API Pitfalls (ALL skills must follow)
- Commerce product search using a broad query → resolve and lock
categoryPathbefore interpreting category-sensitive product, competitor, brand, or price-band results. An explicitly labeledproducts/searchcategory probe may run without a locked category only to resolve that category. Market discovery usesmarkets/searchfilters and returns category IDs; market snapshot, distribution, and history requests use a resolvedcategoryId. Do not apply this rule to/openapi/v2/keywords/*Keyword Intelligence endpoints: theirkeyword/queryinputs are Amazon search queries and do not requirecategoryPath. - Brand/price-band queries MUST include --category to avoid cross-category contamination
- Market revenue: use the full-category or selected-sample field identified in
references/openapi-reference.md § 2; do not calculate revenue from price × sales. - Sales =
monthlySalesFloor(lower bound). Fallback: 300,000 / BSR^0.65, tag as 🔍 - Use API fields directly:
sampleOpportunityIndex,sampleTop10BrandSalesRate— never reinvent - reviews/analysis needs 50+ reviews. Fallback chain when sample is insufficient:
- Lightweight:
realtime/product→ratingBreakdown(star distribution only, no themes) - Full 11-dim insights:
realtime/reviews(raw text, up to 100) + local Map/Reduce via the Local Review Toolkit below — see "Local Review Toolkit" section
- Lightweight:
- Aggregation endpoints (price-band, brand) without categoryPath produce severely distorted data
- Price-band and brand endpoints only accept
keyword(not categoryPath) — cross-validate returned products modeis CLI-local, NOT an API parameter →zoodata.pyexpands--modeclient-side into the filter sets inPRODUCT_MODES({skill_base_dir}/scripts/zoodata.py, 13 presets) before the request; sendingmoderaw → 422- CLI filter flags ≠ API field names →
--sales-min→monthlySalesMin;--ratings-max(review count) →ratingCountMax, notratingMax(a different valid field — max star rating — that returns wrong results silently, no 422). PasscategoryPathas a JSON array (["Electronics"]), never a string. Unknown fields (salesMin,ratingsMax, …) → 422
On Missing Key (no credentials configured)
BEFORE 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:
- STOP. Do not run the workflow. Do not call
zoodata.py(you'll just get the same credential error and burn tokens). - Do NOT fall back to a "partial analysis from training data" / "industry common-sense headlines" / "for reference only" preview. Your training data is stale, has no per-ASIN granularity, and presenting it as analysis — even disclaimed — misrepresents what this skill produces. The deliverable is data-backed; without data, there is no deliverable.
- Tell the user, in their language, all three of:
- "
ZOODATA_API_KEYis not set — I need this to run the analysis." - Get a free key (1,000 credits, no credit card): https://zoodata.ai/en/api-keys
- Configure via one of:
export ZOODATA_API_KEY='hms_live_xxx'(session only)mkdir -p ~/.zoodata && chmod 700 ~/.zoodata && (umask 077; echo '{"api_key":"hms_live_xxx"}' > ~/.zoodata/config.json)(persistent; keep the file private — 0600)
- "
- Optionally state in one sentence what the workflow will produce once the key is configured (deliverable shape only — no numbers, no market color, no "common sense" preview).
On 401 Invalid Key
When zoodata.py returns a structured error with _transport.status=401, apply this route regardless of whether the preserved server error object contains status or uses the CLI fallback message:
- STOP further endpoint calls immediately. Do not retry — a rejected key won't be accepted on a second try; every subsequent call will return 401 too.
- Keep the selected credential authoritative. Do not inspect, compare, export, or switch to a lower-priority legacy credential after rejection. A legacy credential may be selected only when neither new source is configured; trying another endpoint or asking to continue does not change this precedence.
- Report to the user:
- The selected ZooData credential was rejected (likely invalid, revoked, or expired)
- If any partial findings were collected before the failure, show them and mark as partial
- Fix at https://zoodata.ai/en/api-keys (verify the key, regenerate if needed)
- Do not fabricate or guess the data the failed calls would have returned. This includes "training-data fallback" / "industry common-sense" headlines disguised as preview — those are fabrications.
On 402 Credit Exhausted
When zoodata.py returns a structured error with _transport.status=402, apply this route regardless of whether the preserved server error object contains status or uses the CLI fallback message:
- STOP further endpoint calls immediately. Do not retry. Do not switch endpoints as a workaround — 402 is account-level (key/subscription), not endpoint-level.
- Report to the user with all four of:
- Which step in the workflow was reached (e.g. "Completed step 3/5: brand analysis")
- Partial findings already collected (show the actual data, not just a list of completed steps)
- Returned credit metadata when available; if it is absent, say it was not returned rather than estimating it
- Top-up link: https://zoodata.ai/en/pricing
- Do not fabricate or guess the missing data to "complete" the report. Mark partial findings explicitly as partial. No "training-data fallback" / "industry common-sense" filler — substituting public-knowledge prose for missing endpoint data is still fabrication.
On 422 Validation Error
For every parsed HTTP response from zoodata.py, treat _transport.status as the authoritative outer status; response-body and nested status-like fields do not override it. When the CLI returns HTTP 422 / VALIDATION_ERROR, read the preserved structured server error on stdout, including its message/details and _query.params. Do not retry the unchanged request. Correct the named fields first; the CLI exits non-zero while preserving the server error fields for the calling agent. Current keyword requests retain granularity for compatibility but accept only week; legacy lookbackDays remains unsupported.
25 Amazon and Keyword Endpoints
| # | Endpoint | Purpose | Key Output |
|---|---|---|---|
| 1 | categories |
Browse/search category tree | categoryPath, productCount |
| 2 | markets/search |
Paginated discovery or exact category snapshot | categoryId, marketTotal and selected marketSample metrics |
| 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 | data.context + data.items[].snapshotData with estimateSearchCount, abaRank, market/SKU/ad fields |
| 14 | /openapi/v2/keywords/market-profile |
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 | data.context + data.items[].series[] with search count, ABA rank, Top3 shares, period bounds |
| 16 | /openapi/v2/keywords/trend-profile |
Server-calculated trend profile over fixed weekly windows | trend shape, volatility, normalized slope, direction consistency, ABA-rank evidence |
| 17 | /openapi/v2/keywords/extends |
Keyword expansion / long-tail discovery | data.context + data.rows[].{matchData,keywordSnapshot}; may return empty rows[] |
| 18 | /openapi/v2/keywords/search-results |
Weekly keyword SERP snapshot | data.context + data.identity + data.rows[] with placement, product, and impression fields |
| 19 | /openapi/v2/keywords/product-traffic-terms |
Traffic-driving keywords for any target ASIN, including a competitor | data.context + data.identity + data.rows[] with keyword, position, demand, ABA rank, and traffic share |
| 20 | /openapi/v2/keywords/product-traffic-structure-profile |
Current-vs-previous-week ASIN traffic structure and change drivers | data.context + data.items[].productTrafficTermsProfile for one ASIN or a batch of up to 20 |
| 21 | /openapi/v2/keywords/product-traffic-terms-trend |
Per-keyword weekly traffic trend for one ASIN | data.context + data.items[].series[] with nested ASIN, traffic, placement, keyword, and ad groups |
| 22 | /openapi/v2/keywords/product-traffic-trend |
ASIN-level weekly raw traffic across all keywords | data.context + data.items[].series[] with total/organic/ad traffic and term coverage |
| 23 | /openapi/v2/keywords/product-traffic-trend-profile |
Server-calculated four-week ASIN traffic conclusions | data.context + data.items[].rows[].trafficTrendProfile |
| 24 | markets/structure-profile |
One Top 100 distribution | data.buckets[] with four-window newProductMetrics[] |
| 25 | markets/history |
One category's month-end series | data.points[] with marketTotal and marketSample |
Known Quirks
- Market request quirks, including the live
sampleTypevalues and retired parameters, are owned byreferences/openapi-reference.md § 2. listingAgeis a string enum (30d,90d,180d,1y,2y).- Many search/list endpoints return
.dataas an array — use.data[0]for the first record. But some commands may return non-array payloads insidedata, so inspect the actual response shape before indexing. ratingCountnotreviewCounteverywherebsr(int) in products vsbestsellersRank(array) in realtimebuyboxWinner.price— NOT top-levelpricein realtimerealtime/productdoes NOT return: monthlySalesFloor, fbaFee, sellerCountrealtime/productcold-start: first call for an uncached ASIN may returnsuccess: truewith an EMPTYdata(asin: "") while the live fetch warms up — retry once after a few seconds before concluding "no data" (still billed 1 credit per call)reviewCountMin/Maxfilters currently broken (API-56)reviews/analysismay 500 for certain ASINs (API-58) — retry different ASIN- Rate limit: 100 req/min, 10 req/sec burst
categoriesusescategoryKeyword(notkeyword) andparentCategoryPath(notparentCategoryName)reviews/analysis:moderequired ("asin"/"category"), useasins(plural array) notasinrealtime/reviews: returns 10 reviews/page fixed (nopageSizeparam); 1 credit/page; cursor-paginated; hard cap = 100 reviews (10 pages); supportsmarketplaceUS/UK onlykeywords/detailaccepts exactly one ofkeyword/keywords[](max 20), resolvesdateto the nearest available weekly snapshot, and returns input-ordereddata.items[]; an unmatched item hasstatus=empty, not top-leveldata: nullkeywords/market-profileaccepts one ofkeyword/keywords[](max 20), requiresdate, supports weekly granularity only, and returns input-ordereddata.items[]withstatus=ok|empty.emptyReasonis descriptive no-result text, not an enum. A subject-specific calculation failure can return HTTP 500 for the whole batch.keywords/trend-profileaccepts one ofkeyword/keywords[](max 20), requiresdateand 1–4 uniquewindowPeriodsselected from 4/8/12/26, and supports weekly granularity only.keywords/extendsrequiresquery(notkeyword), uses the latest available weekly snapshot, supportsqueryType=phraseorfuzzy, and may legitimately return emptydata.rows[]; the MCP schema has nodateparameter, and the CLI has no--dateoption for this command- All eleven current keyword and product-traffic request schemas retain
granularityfor compatibility and accept onlyweek; all currently support only marketplaceUS. The bundled CLI sends both values explicitly. Never send another granularity or legacylookbackDays. Use returned weekly period boundaries instead of inferring a rolling window. - Batch keyword fields on
detail,market-profile,trend,trend-profile, andproduct-traffic-terms-trendmust already equalLOWER(TRIM(value)); the bundled CLI normalizes them. Single-keyword fields accept surrounding whitespace and letter case where the endpoint schema says so. - Keyword endpoints are keyword-query workflows; for inputs named
keywordorquery, use the Amazon search query / keyword phrase being analyzed - For keyword endpoints that require
dateordateTo, prefer T-1 or earlier and avoid the current date unless the user explicitly asks for today's lookup keywords/search-resultsrequiresdate+keyword;exploreTypesvalues areORG,SP,SB,SBV,SPR- Competitor traffic-term lookup is consolidated into
keywords/product-traffic-terms; route retired-interface behavior and the exact request contract toreferences/openapi-reference.md § 16. keywords/product-traffic-structure-profilecompares the resolved current week with the previous week; it is not a multi-week trend. Seereferences/openapi-reference.md § 17for its exact contract.keywords/product-traffic-trendis ASIN-level across all keywords and has no keyword dimension; useproduct-traffic-terms-trendfor an ASIN × keyword series.keywords/product-traffic-trend-profileprovides the server-calculated ASIN-wide trend profile; route exact window, detail, and billing questions toreferences/openapi-reference.md § 20.keywords/search-resultsis the default source for explaining what products currently appear on a keyword SERP because it already returns listing-level product fieldsproducts/searchis a broader ZooData product-database query and must not be presented as Amazon live keyword SERP ordering
Keyword Intelligence Endpoints
These eleven endpoints fill the gap between raw catalog data and search-demand/search-visibility intelligence.
Keyword value boundary:
- Keyword endpoints provide estimated search, visibility, rank, traffic-share, and impression-point signals
- They do not provide a seller's first-party ABA Search Query Performance funnel by themselves
- Treat keyword value, profitability, and conversion potential as directional unless the user supplies ABA-SQP impressions, clicks, cart adds, purchases, click share, purchase share, and conversion rate
- Seller-artifact acquisition, stage selection, field interpretation, and user-facing output policy belong to the
amazon-keyword-traffic-analysisskill. This API reference does not prescribe a blanket caveat or one seller view for every subject.
/openapi/v2/keywords/detail
- Input: exactly one of
keyword/keywords[](1–20), requireddate, optionalmarketplace; compatibility-retainedgranularitysupports onlyweek - Data window: resolves the requested
dateto the nearest available weekly snapshot at or before that date - Date rule: prefer T-1 or earlier for
date; avoid current-date lookup unless explicitly requested - Response shape:
data.context + data.items[], preserving request order - Item fields:
identity,status=ok|empty,snapshotData,emptyReason, nullableerrorCode, nullableerrorMessage snapshotDatafields includeestimateSearchCount,abaRank, Top3 click/conversion shares,marketCharacteristics,totalSkuCount, SKU/brand/title coverage, organic/ad counts, and Top48 benchmarks- Do not read legacy
estimateSearchCountWeekly,totalSkuCnt, or top-leveldata:null
/openapi/v2/keywords/market-profile (metric layer)
- Availability: standard production endpoint under the documented base URL
- Input: exactly one of
keywordorkeywords[](1–20), requireddate, optionalmarketplace; compatibility-retainedgranularitysupports onlyweek - Response shape:
data.context + data.items[], preserving request order - Context fields:
requestedDate,resolvedDate,dataWindow.currentPeriod,scoringSpec, marketplace/site/granularity - Item fields:
identity,status=ok|empty,marketProfile,emptyReason marketProfiledimensions:marketCharacteristics,demandScale,top3Concentration,adActivity,top20OrganicEntryDifficulty,supplySaturation,brandStructure,organicProductBenchmark- Interpret scores only with
context.scoringSpec(id,version,scoreType,scoreRange,referenceScope). Scored dimensions exposesupported,calculationStatus,unsupportedReason,level,interpretation, andlevelEvidence.score.{value,direction}. There is no aggregate coverage object. marketCharacteristics.volatilityandmarketCharacteristics.annualSeasonalityare independent evidence objects. Do not collapse their classifications, let one override the other, or invent peak periods from an empty list.- Unmatched keywords return
status=empty,marketProfile=null, and a descriptiveemptyReason; resolved context andscoringSpecmay be null - A subject-specific calculation failure can currently produce HTTP 500 for the whole batch. Treat it as a service failure, not an item-level
emptyresult; do not automatically fan out all subjects into single calls. - Three-layer boundary: use data-layer
keywords/detailfor source snapshot fields, metric-layerkeywords/market-profilefor stable deterministic profile objects, and the Agent + skill layer for evidence composition, confidence, explanations, limitations, and actions - Metric-first access: call the matching metric before its source data endpoint. Descend only when the Agent needs an indicator or evidence grain omitted by the metric contract, the metric endpoint is unavailable and transparent data-based calculation is valid, no metric exists, or raw evidence is explicitly requested. Incomplete metric calculation coverage is a conclusion limit—not by itself a reason to call same-source data.
- Batch-first execution: after selecting the endpoint, collect all subjects with identical non-subject context and prefer its batch contract over repeated single calls. Deduplicate case-insensitively, preserve order, chunk compatible sets at the endpoint limit (20 for current keyword batches), and merge results back into global input order. Batch support never justifies an extra cross-layer call.
/openapi/v2/keywords/trend
- Input: exactly one of
keyword/keywords[](1–20), requireddateFrom/dateTo, optionalmarketplace; compatibility-retainedgranularitysupports onlyweek; maximum 93-day range - Data window: weekly-granularity points across the requested date range
- Date rule: prefer T-1 or earlier for
dateTo; avoid current-date lookup unless explicitly requested - Response shape:
data.context + data.items[].series[], preserving request order - Item fields:
identity,status=ok|empty,series[],emptyReason, nullableerrorCode, nullableerrorMessage - Series fields:
periodStartDate,periodEndDate,estimateSearchCount,abaRank,abaTop3ClickShareRate,abaTop3ConversionShareRate
/openapi/v2/keywords/trend-profile (metric layer)
- Input: exactly one of
keyword/keywords[](1–20), requireddate, required uniquewindowPeriods[]selected from 4/8/12/26, optionalmarketplace; compatibility-retainedgranularitysupports onlyweek - Response:
data.context + data.items[].rows[]; every requested window returns one row withrowContext,status=ok|empty,emptyReason, andtrendProfile - Available profiles contain independently guarded
searchDemandandabaRankdimensions withtrend,trendPattern, and{value,direction}entries undertrendEvidence - Evidence includes first/last/change values, normalized slope, direction consistency, aligned/eligible period counts, plus demand volatility/window position or ABA best/worst rank
- Use this metric endpoint before raw
keywords/trendfor trend-shape and volatility judgments. Descend only for required weekly points or fields omitted from the profile. - Preserve null empty reasons rather than inventing one. Billing is per keyword with at least one
status=okwindow; use returned credit metadata.
/openapi/v2/keywords/extends
- Input: required
query; optionalmarketplace,page,pageSize,queryType,sortBy,sortOrder; compatibility-retainedgranularitysupports onlyweek; no date is required - Important quirk: seed field is
query, notkeyword;queryTypesupportsphraseandfuzzy - Data window: latest available weekly snapshot; the MCP schema has no
dateparameter, and the CLI has no--dateoption for this command - Response shape:
data.context + data.query + data.queryType + data.rows[] - Row fields:
matchData.{query,keyword,site,relevanceScore}andkeywordSnapshot, whosedataWindow.currentPeriodand snapshot metrics use the same current field families askeywords/detail - Do not flatten rows to legacy
term,seedKeyword, orestimateSearchCountWeekly; emptyrows[]is normal
/openapi/v2/keywords/search-results
- Input: required
keyword/date; optionalmarketplace,page,pageSize,exploreTypes,sortBy,sortOrder - Compatibility-retained
granularitysupports onlyweek; do not send legacylookbackDays - Data window: latest available weekly period at or before the requested date; use the returned period boundaries
- Date rule: prefer T-1 or earlier for
date; avoid current-date lookup unless explicitly requested - Response shape:
data.context + data.identity + data.rows[] - Row fields include
latestObservedAt,exploreType,absolutePosition,pageIndex,pagePosition,asin,title,brand,price,currency,link,imageLink,rating,ratingCount,recentSales,hasVideo,estimateImpressionPoint,keywordTotalEstimateImpressionPoint - Interpretation rule: use this endpoint first for "what is on page 1 / what products dominate this keyword / what does the SERP look like"
- Do not substitute
products/searchwhen the question is about observed keyword SERP composition or ordering
/openapi/v2/keywords/product-traffic-terms
- Provides traffic-driving keyword rows for any target ASIN, including competitor research; the former competitor-specific lookup is consolidated into this route.
- Read
references/openapi-reference.md § 16for the request, response, field, date, filtering, pagination, retirement, and billing contract. - Apply
references/cli-contract.mdto every result.
/openapi/v2/keywords/product-traffic-structure-profile
- Production supports one ASIN or a batch of up to 20 ASINs, retains
granularitywithweekas its only supported value, and compares the resolved current week with the previous week. - Read
references/openapi-reference.md § 17for the request, response, status, field, date, batching, and billing contract. - Apply
references/cli-contract.mdto every result, including a server-provided endpoint migration response.
/openapi/v2/keywords/product-traffic-terms-trend
- Provides weekly product-side traffic, placement, keyword-context, and product-observation history for one ASIN and its named keyword subjects.
- Read
references/openapi-reference.md § 18for the request, response, status, field, date, batching, range, and billing contract. - Apply
references/cli-contract.mdto every result.
/openapi/v2/keywords/product-traffic-trend
- Provides ASIN-wide raw weekly traffic and term-coverage history across all observed keywords; it is the weekly-detail companion to the four-week metric profile.
- Read
references/openapi-reference.md § 19for the request, response, status, field, date, batching, and billing contract. - Apply
references/cli-contract.mdto every result.
/openapi/v2/keywords/product-traffic-trend-profile
- Provides the server-calculated ASIN-wide four-week trend profile; use the raw trend endpoint when weekly points are required.
- Read
references/openapi-reference.md § 20for the request, response, status, field, date, batching, and billing contract. - Apply
references/cli-contract.mdto every result.
Local Review Toolkit
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:
- ASIN has fewer than 50 reviews
reviews/analysisreturns sparseconsumerInsights(missing dimensions)- Need the freshest possible data (Spider scrape vs. T+1 BigQuery snapshot)
- Need to analyze a brand-new product that has no daily snapshot yet
Field Differences Across Endpoints
Load references/reference.md § Field Differences Across Endpoints for the cross-endpoint field map.
Confidence Labels (all skills)
- 📊 Data-backed — direct API data
- 🔍 Inferred — logical reasoning from data
- 💡 Directional — suggestions, predictions
Strategy recommendations and subjective conclusions are NEVER 📊. Extreme growth (>200%) = 💡 only.
Data Notes
- Sales (
monthlySalesFloor) = lower-bound estimate - Realtime = live; products/competitors = ~T+1 delay
- Marketplace coverage varies by endpoint; follow each endpoint schema
- Each call consumes credits; check
meta.creditsConsumed
Links
| 1 | |
| 2 | name zoodata |
| 3 | description > |
| 4 | API endpoint reference for ZooData's Amazon commerce and keyword-intelligence |
| 5 | surfaces, including request/response schemas, parameter quirks, authentication, |
| 6 | credit metadata, product-traffic structure and trend APIs, and the Local Review |
| 7 | Toolkit. |
| 8 | Use when the user asks about the API itself: which endpoints exist, how |
| 9 | to call them (e.g. /products/search), field schemas returned by an |
| 10 | endpoint, parameter quirks, how to authenticate, how credit consumption |
| 11 | is reported, how to get started, or how the Local Review Toolkit works. |
| 12 | Requires ZOODATA_API_KEY. |
| 13 | metadata |
| 14 | version "1.3.0" |
| 15 | author SerendipityOneInc |
| 16 | homepage https://github.com/SerendipityOneInc/ZooData-Skills |
| 17 | openclaw {"requires": {"env": ["ZOODATA_API_KEY"]}, "primaryEnv": "ZOODATA_API_KEY"} |
| 18 | |
| 19 | |
| 20 | > **📋 Live API Reference**: Field names and parameters may change. For MCP calls, refresh and |
| 21 | > inspect the current ZooData MCP `inputSchema`; for direct HTTP calls, also consult the OpenAPI |
| 22 | > spec at https://zoodata.ai/api/v1/openapi-spec. |
| 23 | > Keyword compatibility field: all eleven current keyword and product-traffic request schemas |
| 24 | > retain `granularity`, but the only supported value is `week`. The bundled CLI always sends |
| 25 | > `granularity=week`. Never send `day`, `month`, `lately_day`, or legacy `lookbackDays`; use the |
| 26 | > weekly period boundaries returned by the service. |
| 27 | |
| 28 | # ZooData — Commerce Data Infrastructure for AI Agents |
| 29 | |
| 30 | 200M+ Amazon products. 25 Amazon and keyword-intelligence endpoints. One API key. |
| 31 | |
| 32 | ## Quick Start |
| 33 | Get key: [zoodata.ai/api-keys] (1,000 free credits) |
| 34 | `export ZOODATA_API_KEY='hms_live_xxx'` |
| 35 | Base URL: `https://api.zoodata.ai/openapi/v2` — all POST with JSON body |
| 36 | Auth: `Authorization: Bearer YOUR_API_KEY` |
| 37 | New keys need 3-5s to activate. If 403, wait and retry. |
| 38 | |
| 39 | ## Capabilities & Data Flow |
| 40 | |
| 41 | **Network**: only `https://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. |
| 42 | **Execution**: bundled shared ZooData CLI `{skill_base_dir}/scripts/zoodata.py` (Python 3, stdlib-only). This data-layer reference skill allows the complete literal subcommand surface exposed by the bundled client's current top-level help. |
| 43 | **Local files**: none by default; reads the optional credential store `~/.zoodata/config.json`; the Local Review Toolkit uses a private temporary working dir (created with `mktemp -d`, removed when the fallback completes) during the review fallback. |
| 44 | **Sent to the API**: keywords, category paths, ASINs, marketplace/date and numeric filter values only. **Never sent**: budget, experience level, risk tolerance, or any other user-profile text — profile inputs map client-side to numeric filters. |
| 45 | **Credits**: every API call consumes account credits. For broad or ambiguous requests, state the estimated credit cost and confirm with the user before running multi-call scans. |
| 46 | |
| 47 | ## Shared CLI contract |
| 48 | |
| 49 | Before selecting or invoking a bundled CLI command, read and apply `references/cli-contract.md`; reapply it after every result. It is the local source of truth for invocation, command identity, execution-environment permission handling, composite reuse, exit-status handling, authoritative transport status, retries, terminal interface failures, and partial results. |
| 50 | |
| 51 | For market endpoint schemas and quirks, load `references/openapi-reference.md § 2`; that file owns their request and response contracts. `references/reference.md` is a summary index and links to the owner instead of restating the market schemas. |
| 52 | |
| 53 | ### Local Interface Failure Output |
| 54 | |
| 55 | For this API-reference skill, a terminal interface failure must produce one concise localized notice stating that the ZooData API lookup could not be completed, followed by the succeeded and failed endpoint identifiers. Do not continue into endpoint guidance, schema interpretation, or another API call. Do not expose control tokens or internal retry logs unless the user requests diagnostics. |
| 56 | |
| 57 | ## ⚠️ Critical API Pitfalls (ALL skills must follow) |
| 58 | **Commerce product search using a broad query** → resolve and lock `categoryPath` before interpreting category-sensitive product, competitor, brand, or price-band results. An explicitly labeled `products/search` category probe may run without a locked category only to resolve that category. Market discovery uses `markets/search` filters and returns category IDs; market snapshot, distribution, and history requests use a resolved `categoryId`. Do **not** apply this rule to `/openapi/v2/keywords/*` Keyword Intelligence endpoints: their `keyword` / `query` inputs are Amazon search queries and do not require `categoryPath`. |
| 59 | **Brand/price-band queries MUST include --category** to avoid cross-category contamination |
| 60 | **Market revenue**: use the full-category or selected-sample field identified in `references/openapi-reference.md § 2`; do not calculate revenue from price × sales. |
| 61 | **Sales** = `monthlySalesFloor` (lower bound). Fallback: 300,000 / BSR^0.65, tag as 🔍 |
| 62 | **Use API fields directly**: `sampleOpportunityIndex`, `sampleTop10BrandSalesRate` — never reinvent |
| 63 | **reviews/analysis** needs 50+ reviews. Fallback chain when sample is insufficient: |
| 64 | Lightweight: `realtime/product` → `ratingBreakdown` (star distribution only, no themes) |
| 65 | Full 11-dim insights: `realtime/reviews` (raw text, up to 100) + local Map/Reduce via the |
| 66 | Local Review Toolkit below — see "Local Review Toolkit" section |
| 67 | **Aggregation endpoints** (price-band, brand) without categoryPath produce severely distorted data |
| 68 | **Price-band and brand endpoints only accept `keyword`** (not categoryPath) — cross-validate returned products |
| 69 | **`mode` 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 |
| 70 | **CLI filter flags ≠ API field names** → `--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`, …) → 422 |
| 71 | |
| 72 | ## On Missing Key (no credentials configured) |
| 73 | |
| 74 | **BEFORE 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. |
| 75 | |
| 76 | When no key is found through any mechanism: |
| 77 | |
| 78 | **STOP.** Do not run the workflow. Do not call `zoodata.py` (you'll just get the same credential error and burn tokens). |
| 79 | **Do NOT fall back to a "partial analysis from training data" / "industry common-sense headlines" / "for reference only" preview.** Your training data is stale, has no per-ASIN granularity, and presenting it as analysis — even disclaimed — misrepresents what this skill produces. The deliverable is data-backed; without data, there is no deliverable. |
| 80 | **Tell the user, in their language**, all three of: |
| 81 | "`ZOODATA_API_KEY` is not set — I need this to run the analysis." |
| 82 | **Get a free key** (1,000 credits, no credit card): https://zoodata.ai/en/api-keys |
| 83 | **Configure** via one of: |
| 84 | `export ZOODATA_API_KEY='hms_live_xxx'` (session only) |
| 85 | `mkdir -p ~/.zoodata && chmod 700 ~/.zoodata && (umask 077; echo '{"api_key":"hms_live_xxx"}' > ~/.zoodata/config.json)` (persistent; keep the file private — 0600) |
| 86 | **Optionally** state in **one sentence** what the workflow will produce once the key is configured (deliverable shape only — no numbers, no market color, no "common sense" preview). |
| 87 | |
| 88 | ## On 401 Invalid Key |
| 89 | |
| 90 | When `zoodata.py` returns a structured error with `_transport.status=401`, apply this route regardless of whether the preserved server `error` object contains `status` or uses the CLI fallback message: |
| 91 | |
| 92 | **STOP further endpoint calls immediately.** Do not retry — a rejected key won't be accepted on a second try; every subsequent call will return 401 too. |
| 93 | **Keep the selected credential authoritative.** Do not inspect, compare, export, or switch to a lower-priority legacy credential after rejection. A legacy credential may be selected only when neither new source is configured; trying another endpoint or asking to continue does not change this precedence. |
| 94 | **Report to the user**: |
| 95 | The selected ZooData credential was rejected (likely invalid, revoked, or expired) |
| 96 | If any partial findings were collected before the failure, show them and mark as partial |
| 97 | Fix at https://zoodata.ai/en/api-keys (verify the key, regenerate if needed) |
| 98 | **Do not fabricate or guess** the data the failed calls would have returned. This includes "training-data fallback" / "industry common-sense" headlines disguised as preview — those are fabrications. |
| 99 | |
| 100 | ## On 402 Credit Exhausted |
| 101 | |
| 102 | When `zoodata.py` returns a structured error with `_transport.status=402`, apply this route regardless of whether the preserved server `error` object contains `status` or uses the CLI fallback message: |
| 103 | |
| 104 | **STOP further endpoint calls immediately.** Do not retry. Do not switch endpoints as a workaround — 402 is account-level (key/subscription), not endpoint-level. |
| 105 | **Report to the user** with all four of: |
| 106 | Which step in the workflow was reached (e.g. "Completed step 3/5: brand analysis") |
| 107 | Partial findings already collected (show the actual data, not just a list of completed steps) |
| 108 | Returned credit metadata when available; if it is absent, say it was not returned rather than estimating it |
| 109 | Top-up link: https://zoodata.ai/en/pricing |
| 110 | **Do not fabricate or guess** the missing data to "complete" the report. Mark partial findings explicitly as partial. **No "training-data fallback" / "industry common-sense" filler** — substituting public-knowledge prose for missing endpoint data is still fabrication. |
| 111 | |
| 112 | ## On 422 Validation Error |
| 113 | |
| 114 | For every parsed HTTP response from `zoodata.py`, treat `_transport.status` as the authoritative outer status; response-body and nested status-like fields do not override it. When the CLI returns HTTP 422 / `VALIDATION_ERROR`, read the preserved structured server error on stdout, including its message/details and `_query.params`. Do not retry the unchanged request. Correct the named fields first; the CLI exits non-zero while preserving the server error fields for the calling agent. Current keyword requests retain `granularity` for compatibility but accept only `week`; legacy `lookbackDays` remains unsupported. |
| 115 | |
| 116 | ## 25 Amazon and Keyword Endpoints |
| 117 | |
| 118 | | # | Endpoint | Purpose | Key Output | |
| 119 | |---|----------|---------|------------| |
| 120 | | 1 | `categories` | Browse/search category tree | categoryPath, productCount | |
| 121 | | 2 | `markets/search` | Paginated discovery or exact category snapshot | categoryId, `marketTotal` and selected `marketSample` metrics | |
| 122 | | 3 | `products/search` | Product search (20+ filter fields) | asin, price, monthlySalesFloor, rating, ratingCount, fbaFee | |
| 123 | | 4 | `products/competitors` | Competitor discovery | same fields as products/search | |
| 124 | | 5 | `realtime/product` | Live ASIN detail | rating, features, bestsellersRank[], buyboxWinner.price, variants | |
| 125 | | 6 | `reviews/analysis` | AI review insights (11 dims) | sentimentDistribution, consumerInsights, topKeywords | |
| 126 | | 7 | `realtime/reviews` | Live raw review text (cursor paginated, max 100) | reviews[], nextCursor — feeds Local Review Toolkit | |
| 127 | | 8 | `products/price-band-overview` | Price band summary | hottestBand, bestOpportunityBand, sampleOpportunityIndex | |
| 128 | | 9 | `products/price-band-detail` | Full 5-band distribution | priceBands[] with sales, brands, ratings per band | |
| 129 | | 10 | `products/brand-overview` | Brand concentration | sampleTop10BrandSalesRate (CR10), sampleBrandCount | |
| 130 | | 11 | `products/brand-detail` | Per-brand breakdown | brands[] with sales, revenue, sampleProducts | |
| 131 | | 12 | `products/history` | Time series (single ASIN per call) | timestamps[], price[], bsr[], monthlySalesFloor[], rating[], ratingCount[], sellerCount[], title/imageUrl/bestSeller/newRelease/aPlus/inventoryStatus changelogs | |
| 132 | | 13 | `/openapi/v2/keywords/detail` | Keyword summary from the nearest available weekly snapshot | `data.context + data.items[].snapshotData` with `estimateSearchCount`, `abaRank`, market/SKU/ad fields | |
| 133 | | 14 | `/openapi/v2/keywords/market-profile` | Multidimensional weekly keyword profile | demand scale, Top3 concentration, ad activity, organic-entry difficulty, saturation, brand structure, organic benchmark, coverage | |
| 134 | | 15 | `/openapi/v2/keywords/trend` | Weekly keyword time series | `data.context + data.items[].series[]` with search count, ABA rank, Top3 shares, period bounds | |
| 135 | | 16 | `/openapi/v2/keywords/trend-profile` | Server-calculated trend profile over fixed weekly windows | trend shape, volatility, normalized slope, direction consistency, ABA-rank evidence | |
| 136 | | 17 | `/openapi/v2/keywords/extends` | Keyword expansion / long-tail discovery | `data.context + data.rows[].{matchData,keywordSnapshot}`; may return empty `rows[]` | |
| 137 | | 18 | `/openapi/v2/keywords/search-results` | Weekly keyword SERP snapshot | `data.context + data.identity + data.rows[]` with placement, product, and impression fields | |
| 138 | | 19 | `/openapi/v2/keywords/product-traffic-terms` | Traffic-driving keywords for any target ASIN, including a competitor | `data.context + data.identity + data.rows[]` with keyword, position, demand, ABA rank, and traffic share | |
| 139 | | 20 | `/openapi/v2/keywords/product-traffic-structure-profile` | Current-vs-previous-week ASIN traffic structure and change drivers | `data.context + data.items[].productTrafficTermsProfile` for one ASIN or a batch of up to 20 | |
| 140 | | 21 | `/openapi/v2/keywords/product-traffic-terms-trend` | Per-keyword weekly traffic trend for one ASIN | `data.context + data.items[].series[]` with nested ASIN, traffic, placement, keyword, and ad groups | |
| 141 | | 22 | `/openapi/v2/keywords/product-traffic-trend` | ASIN-level weekly raw traffic across all keywords | `data.context + data.items[].series[]` with total/organic/ad traffic and term coverage | |
| 142 | | 23 | `/openapi/v2/keywords/product-traffic-trend-profile` | Server-calculated four-week ASIN traffic conclusions | `data.context + data.items[].rows[].trafficTrendProfile` | |
| 143 | | 24 | `markets/structure-profile` | One Top 100 distribution | data.buckets[] with four-window `newProductMetrics[]` | |
| 144 | | 25 | `markets/history` | One category's month-end series | data.points[] with `marketTotal` and `marketSample` | |
| 145 | |
| 146 | ## Known Quirks |
| 147 | Market request quirks, including the live `sampleType` values and retired parameters, are owned by `references/openapi-reference.md § 2`. |
| 148 | `listingAge` is a string enum (`30d`, `90d`, `180d`, `1y`, `2y`). |
| 149 | Many search/list endpoints return `.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. |
| 150 | `ratingCount` not `reviewCount` everywhere |
| 151 | `bsr` (int) in products vs `bestsellersRank` (array) in realtime |
| 152 | `buyboxWinner.price` — NOT top-level `price` in realtime |
| 153 | `realtime/product` does NOT return: monthlySalesFloor, fbaFee, sellerCount |
| 154 | `realtime/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) |
| 155 | `reviewCountMin/Max` filters currently broken (API-56) |
| 156 | `reviews/analysis` may 500 for certain ASINs (API-58) — retry different ASIN |
| 157 | Rate limit: 100 req/min, 10 req/sec burst |
| 158 | `categories` uses `categoryKeyword` (not `keyword`) and `parentCategoryPath` (not `parentCategoryName`) |
| 159 | `reviews/analysis`: `mode` required ("asin"/"category"), use `asins` (plural array) not `asin` |
| 160 | `realtime/reviews`: returns 10 reviews/page fixed (no `pageSize` param); 1 credit/page; cursor-paginated; hard cap = 100 reviews (10 pages); supports `marketplace` US/UK only |
| 161 | `keywords/detail` accepts exactly one of `keyword` / `keywords[]` (max 20), resolves `date` to the nearest available weekly snapshot, and returns input-ordered `data.items[]`; an unmatched item has `status=empty`, not top-level `data: null` |
| 162 | `keywords/market-profile` accepts one of `keyword` / `keywords[]` (max 20), requires `date`, supports weekly granularity only, and returns input-ordered `data.items[]` with `status=ok|empty`. `emptyReason` is descriptive no-result text, not an enum. A subject-specific calculation failure can return HTTP 500 for the whole batch. |
| 163 | `keywords/trend-profile` accepts one of `keyword` / `keywords[]` (max 20), requires `date` and 1–4 unique `windowPeriods` selected from 4/8/12/26, and supports weekly granularity only. |
| 164 | `keywords/extends` requires `query` (not `keyword`), uses the latest available weekly snapshot, supports `queryType` = `phrase` or `fuzzy`, and may legitimately return empty `data.rows[]`; the MCP schema has no `date` parameter, and the CLI has no `--date` option for this command |
| 165 | All eleven current keyword and product-traffic request schemas retain `granularity` for compatibility and accept only `week`; all currently support only marketplace `US`. The bundled CLI sends both values explicitly. Never send another granularity or legacy `lookbackDays`. Use returned weekly period boundaries instead of inferring a rolling window. |
| 166 | Batch keyword fields on `detail`, `market-profile`, `trend`, `trend-profile`, and `product-traffic-terms-trend` must already equal `LOWER(TRIM(value))`; the bundled CLI normalizes them. Single-keyword fields accept surrounding whitespace and letter case where the endpoint schema says so. |
| 167 | Keyword endpoints are keyword-query workflows; for inputs named `keyword` or `query`, use the Amazon search query / keyword phrase being analyzed |
| 168 | For keyword endpoints that require `date` or `dateTo`, prefer T-1 or earlier and avoid the current date unless the user explicitly asks for today's lookup |
| 169 | `keywords/search-results` requires `date` + `keyword`; `exploreTypes` values are `ORG`, `SP`, `SB`, `SBV`, `SPR` |
| 170 | Competitor traffic-term lookup is consolidated into `keywords/product-traffic-terms`; route retired-interface behavior and the exact request contract to `references/openapi-reference.md § 16`. |
| 171 | `keywords/product-traffic-structure-profile` compares the resolved current week with the previous week; it is not a multi-week trend. See `references/openapi-reference.md § 17` for its exact contract. |
| 172 | `keywords/product-traffic-trend` is ASIN-level across all keywords and has no keyword dimension; use `product-traffic-terms-trend` for an ASIN × keyword series. |
| 173 | `keywords/product-traffic-trend-profile` provides the server-calculated ASIN-wide trend profile; route exact window, detail, and billing questions to `references/openapi-reference.md § 20`. |
| 174 | `keywords/search-results` is the default source for explaining what products currently appear on a keyword SERP because it already returns listing-level product fields |
| 175 | `products/search` is a broader ZooData product-database query and must not be presented as Amazon live keyword SERP ordering |
| 176 | |
| 177 | ## Keyword Intelligence Endpoints |
| 178 | |
| 179 | These eleven endpoints fill the gap between raw |
| 180 | catalog data and search-demand/search-visibility intelligence. |
| 181 | |
| 182 | Keyword value boundary: |
| 183 | Keyword endpoints provide estimated search, visibility, rank, traffic-share, and impression-point signals |
| 184 | They do not provide a seller's first-party ABA Search Query Performance funnel by themselves |
| 185 | Treat keyword value, profitability, and conversion potential as directional unless the user supplies ABA-SQP impressions, clicks, cart adds, purchases, click share, purchase share, and conversion rate |
| 186 | Seller-artifact acquisition, stage selection, field interpretation, and user-facing output policy belong to the `amazon-keyword-traffic-analysis` skill. This API reference does not prescribe a blanket caveat or one seller view for every subject. |
| 187 | |
| 188 | ### `/openapi/v2/keywords/detail` |
| 189 | Input: exactly one of `keyword` / `keywords[]` (1–20), required `date`, optional `marketplace`; compatibility-retained `granularity` supports only `week` |
| 190 | Data window: resolves the requested `date` to the nearest available weekly snapshot at or before that date |
| 191 | Date rule: prefer T-1 or earlier for `date`; avoid current-date lookup unless explicitly requested |
| 192 | Response shape: `data.context + data.items[]`, preserving request order |
| 193 | Item fields: `identity`, `status=ok|empty`, `snapshotData`, `emptyReason`, nullable `errorCode`, nullable `errorMessage` |
| 194 | `snapshotData` fields include `estimateSearchCount`, `abaRank`, Top3 click/conversion shares, |
| 195 | `marketCharacteristics`, `totalSkuCount`, SKU/brand/title coverage, organic/ad counts, and Top48 benchmarks |
| 196 | Do not read legacy `estimateSearchCountWeekly`, `totalSkuCnt`, or top-level `data:null` |
| 197 | |
| 198 | ### `/openapi/v2/keywords/market-profile` (metric layer) |
| 199 | Availability: standard production endpoint under the documented base URL |
| 200 | Input: exactly one of `keyword` or `keywords[]` (1–20), required `date`, optional `marketplace`; compatibility-retained `granularity` supports only `week` |
| 201 | Response shape: `data.context + data.items[]`, preserving request order |
| 202 | Context fields: `requestedDate`, `resolvedDate`, `dataWindow.currentPeriod`, `scoringSpec`, marketplace/site/granularity |
| 203 | Item fields: `identity`, `status=ok|empty`, `marketProfile`, `emptyReason` |
| 204 | `marketProfile` dimensions: `marketCharacteristics`, `demandScale`, `top3Concentration`, `adActivity`, `top20OrganicEntryDifficulty`, `supplySaturation`, `brandStructure`, `organicProductBenchmark` |
| 205 | Interpret scores only with `context.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. |
| 206 | `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. |
| 207 | Unmatched keywords return `status=empty`, `marketProfile=null`, and a descriptive `emptyReason`; resolved context and `scoringSpec` may be null |
| 208 | A subject-specific calculation failure can currently produce HTTP 500 for the whole batch. Treat it as a service failure, not an item-level `empty` result; do not automatically fan out all subjects into single calls. |
| 209 | Three-layer boundary: use data-layer `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 |
| 210 | Metric-first access: call the matching metric before its source data endpoint. Descend only when the Agent needs an indicator or evidence grain omitted by the metric contract, the metric endpoint is unavailable and transparent data-based calculation is valid, no metric exists, or raw evidence is explicitly requested. Incomplete metric calculation coverage is a conclusion limit—not by itself a reason to call same-source data. |
| 211 | Batch-first execution: after selecting the endpoint, collect all subjects with identical non-subject context and prefer its batch contract over repeated single calls. Deduplicate case-insensitively, preserve order, chunk compatible sets at the endpoint limit (20 for current keyword batches), and merge results back into global input order. Batch support never justifies an extra cross-layer call. |
| 212 | |
| 213 | ### `/openapi/v2/keywords/trend` |
| 214 | Input: exactly one of `keyword` / `keywords[]` (1–20), required `dateFrom` / `dateTo`, optional `marketplace`; compatibility-retained `granularity` supports only `week`; maximum 93-day range |
| 215 | Data window: weekly-granularity points across the requested date range |
| 216 | Date rule: prefer T-1 or earlier for `dateTo`; avoid current-date lookup unless explicitly requested |
| 217 | Response shape: `data.context + data.items[].series[]`, preserving request order |
| 218 | Item fields: `identity`, `status=ok|empty`, `series[]`, `emptyReason`, nullable `errorCode`, nullable `errorMessage` |
| 219 | Series fields: `periodStartDate`, `periodEndDate`, `estimateSearchCount`, `abaRank`, |
| 220 | `abaTop3ClickShareRate`, `abaTop3ConversionShareRate` |
| 221 | |
| 222 | ### `/openapi/v2/keywords/trend-profile` (metric layer) |
| 223 | Input: exactly one of `keyword` / `keywords[]` (1–20), required `date`, required unique `windowPeriods[]` selected from 4/8/12/26, optional `marketplace`; compatibility-retained `granularity` supports only `week` |
| 224 | Response: `data.context + data.items[].rows[]`; every requested window returns one row with `rowContext`, `status=ok|empty`, `emptyReason`, and `trendProfile` |
| 225 | Available profiles contain independently guarded `searchDemand` and `abaRank` dimensions with `trend`, `trendPattern`, and `{value,direction}` entries under `trendEvidence` |
| 226 | Evidence includes first/last/change values, normalized slope, direction consistency, aligned/eligible period counts, plus demand volatility/window position or ABA best/worst rank |
| 227 | Use this metric endpoint before raw `keywords/trend` for trend-shape and volatility judgments. Descend only for required weekly points or fields omitted from the profile. |
| 228 | Preserve null empty reasons rather than inventing one. Billing is per keyword with at least one `status=ok` window; use returned credit metadata. |
| 229 | |
| 230 | ### `/openapi/v2/keywords/extends` |
| 231 | Input: required `query`; optional `marketplace`, `page`, `pageSize`, `queryType`, `sortBy`, `sortOrder`; compatibility-retained `granularity` supports only `week`; no date is required |
| 232 | Important quirk: seed field is `query`, not `keyword`; `queryType` supports `phrase` and `fuzzy` |
| 233 | Data window: latest available weekly snapshot; the MCP schema has no `date` parameter, and the CLI has no `--date` option for this command |
| 234 | Response shape: `data.context + data.query + data.queryType + data.rows[]` |
| 235 | Row fields: `matchData.{query,keyword,site,relevanceScore}` and `keywordSnapshot`, whose |
| 236 | `dataWindow.currentPeriod` and snapshot metrics use the same current field families as `keywords/detail` |
| 237 | Do not flatten rows to legacy `term`, `seedKeyword`, or `estimateSearchCountWeekly`; empty `rows[]` is normal |
| 238 | |
| 239 | ### `/openapi/v2/keywords/search-results` |
| 240 | Input: required `keyword` / `date`; optional `marketplace`, `page`, `pageSize`, `exploreTypes`, `sortBy`, `sortOrder` |
| 241 | Compatibility-retained `granularity` supports only `week`; do not send legacy `lookbackDays` |
| 242 | Data window: latest available weekly period at or before the requested date; use the returned period boundaries |
| 243 | Date rule: prefer T-1 or earlier for `date`; avoid current-date lookup unless explicitly requested |
| 244 | Response shape: `data.context + data.identity + data.rows[]` |
| 245 | Row fields include `latestObservedAt`, `exploreType`, `absolutePosition`, `pageIndex`, |
| 246 | `pagePosition`, `asin`, `title`, `brand`, `price`, `currency`, `link`, `imageLink`, `rating`, |
| 247 | `ratingCount`, `recentSales`, `hasVideo`, `estimateImpressionPoint`, |
| 248 | `keywordTotalEstimateImpressionPoint` |
| 249 | Interpretation rule: use this endpoint first for "what is on page 1 / what products dominate this keyword / what does the SERP look like" |
| 250 | Do not substitute `products/search` when the question is about observed keyword SERP composition or ordering |
| 251 | |
| 252 | ### `/openapi/v2/keywords/product-traffic-terms` |
| 253 | Provides traffic-driving keyword rows for any target ASIN, including competitor research; the former competitor-specific lookup is consolidated into this route. |
| 254 | Read `references/openapi-reference.md § 16` for the request, response, field, date, filtering, pagination, retirement, and billing contract. |
| 255 | Apply `references/cli-contract.md` to every result. |
| 256 | |
| 257 | ### `/openapi/v2/keywords/product-traffic-structure-profile` |
| 258 | Production supports one ASIN or a batch of up to 20 ASINs, retains `granularity` with `week` as its only supported value, and compares the resolved current week with the previous week. |
| 259 | Read `references/openapi-reference.md § 17` for the request, response, status, field, date, batching, and billing contract. |
| 260 | Apply `references/cli-contract.md` to every result, including a server-provided endpoint migration response. |
| 261 | |
| 262 | ### `/openapi/v2/keywords/product-traffic-terms-trend` |
| 263 | Provides weekly product-side traffic, placement, keyword-context, and product-observation history for one ASIN and its named keyword subjects. |
| 264 | Read `references/openapi-reference.md § 18` for the request, response, status, field, date, batching, range, and billing contract. |
| 265 | Apply `references/cli-contract.md` to every result. |
| 266 | |
| 267 | ### `/openapi/v2/keywords/product-traffic-trend` |
| 268 | Provides ASIN-wide raw weekly traffic and term-coverage history across all observed keywords; it is the weekly-detail companion to the four-week metric profile. |
| 269 | Read `references/openapi-reference.md § 19` for the request, response, status, field, date, batching, and billing contract. |
| 270 | Apply `references/cli-contract.md` to every result. |
| 271 | |
| 272 | ### `/openapi/v2/keywords/product-traffic-trend-profile` |
| 273 | Provides the server-calculated ASIN-wide four-week trend profile; use the raw trend endpoint when weekly points are required. |
| 274 | Read `references/openapi-reference.md § 20` for the request, response, status, field, date, batching, and billing contract. |
| 275 | Apply `references/cli-contract.md` to every result. |
| 276 | |
| 277 | ## Local Review Toolkit |
| 278 | |
| 279 | When `/reviews/analysis` lacks aggregation (ASIN has <50 reviews or no daily snapshot), |
| 280 | fall back to live raw reviews + your own LLM. The toolkit does NOT call any external |
| 281 | LLM — you (the calling skill's LLM) perform the Map/Reduce steps. |
| 282 | |
| 283 | **Workflow:** |
| 284 | |
| 285 | |
| 286 | # 1. Fetch raw reviews (up to 100, cursor-paginated, ~60s, 10 credits at full) |
| 287 | zoodata.py reviews-raw --asin B0XXXXXXXX [--marketplace US] [--max-pages 10] |
| 288 | |
| 289 | # 2. For EACH review, render the per-review Map prompt |
| 290 | zoodata.py review-tag-prompt --review '<single review JSON>' \ |
| 291 | [--product-title "..."] [--product-category "..."] |
| 292 | # → Your LLM produces a JSON object with sentiment + 11 dimension arrays |
| 293 | # (mentioned_scenarios, mentioned_issues, mentioned_positives, mentioned_improvements, |
| 294 | # mentioned_buying_factors, mentioned_pain_points, user_profiles, mentioned_usage_times, |
| 295 | # mentioned_usage_locations, mentioned_behaviors, keywords) |
| 296 | # Suggested map parallelism: ~20 concurrent if your LLM supports it |
| 297 | |
| 298 | # 3. Collect candidate phrases per dimension. For EACH dimension render the Reduce prompt |
| 299 | zoodata.py review-reduce-prompt --label-type positives \ |
| 300 | --candidates '["comfortable","comfy","very comfortable",...]' |
| 301 | # → Your LLM produces {clusters: [{canonical, members}, ...]} |
| 302 | # Suggested chunk size for `keywords` dim when >150 candidates: 150 per call |
| 303 | |
| 304 | # 4. Aggregate into reviews/analysis-compatible consumerInsights |
| 305 | zoodata.py review-aggregate --reviews raw.json --tagged tags.json --clusters clusters.json |
| 306 | # → Output shape matches /reviews/analysis: reviewCount, avgRating, |
| 307 | # sentimentDistribution, consumerInsights[], topKeywords[] |
| 308 | |
| 309 | |
| 310 | **When to use the toolkit instead of `reviews/analysis`:** |
| 311 | ASIN has fewer than 50 reviews |
| 312 | `reviews/analysis` returns sparse `consumerInsights` (missing dimensions) |
| 313 | Need the freshest possible data (Spider scrape vs. T+1 BigQuery snapshot) |
| 314 | Need to analyze a brand-new product that has no daily snapshot yet |
| 315 | |
| 316 | ## Field Differences Across Endpoints |
| 317 | |
| 318 | Load `references/reference.md § Field Differences Across Endpoints` for the cross-endpoint field map. |
| 319 | |
| 320 | ## Confidence Labels (all skills) |
| 321 | 📊 **Data-backed** — direct API data |
| 322 | 🔍 **Inferred** — logical reasoning from data |
| 323 | 💡 **Directional** — suggestions, predictions |
| 324 | |
| 325 | Strategy recommendations and subjective conclusions are NEVER 📊. Extreme growth (>200%) = 💡 only. |
| 326 | |
| 327 | ## Data Notes |
| 328 | Sales (`monthlySalesFloor`) = lower-bound estimate |
| 329 | Realtime = live; products/competitors = ~T+1 delay |
| 330 | Marketplace coverage varies by endpoint; follow each endpoint schema |
| 331 | Each call consumes credits; check `meta.creditsConsumed` |
| 332 | |
| 333 | ## Links |
| 334 | [zoodata.ai] · [API Docs] · [GitHub] · [email protected] |
| 335 |
Discussion
Browse more free Claude skills or everything in Development.