linkfox-amazon-ads-report
One-stop skill for obtaining Amazon Ads reports, covering all report types of Sponsored Products (SP) / Sponsored Brands (SB). The script automatically completes report creation, waiting, downloading, and decompression, and directly returns readable structured data. The valid report types and their column lists/groupBy/filters are sourced from `references/report-types/<adProduct-dir>/<reportTypeId>.md` as the single source of truth. This skill is triggered when users mention pulling Amazon Ads reports, downloading Amazon Ads reports, or obtaining any reports such as SP/SB campaigns, keywords, search terms, advertised products, purchased products, ad groups, traffic anomalies, Prompt extensions, etc. This skill depends on linkfox-amazon-ads-auth. Sponsored Display (SD) / Sponsored Television (ST) / Amazon DSP are not covered yet.
NPX Install
npx skill4agent add linkfox-ai/linkfox-skills linkfox-amazon-ads-reportTags
Translated version includes tags in frontmatterSKILL.md Content (Chinese)
View Translation Comparison →Amazon Ads Report Retrieval
.mdreferences/report-types/linkfox-amazon-ads-authDEPENDENCY_MISSING⚠️ Multi-account scenario: Must resolve the profileId before calling
profileId- First call of
authorized_stores.pyto pull the list of user-authorized accounts × sites.linkfox-amazon-ads-auth - Match candidate profiles based on the site mentioned by the user (mapped to , e.g., US→
countryCode):US- Only 1 candidate → Silently take the corresponding profileId and proceed with the call; do not announce the profileId number to the user.
- ≥ 2 candidates (multiple authorized accounts under the same site) → Must clarify with the user, using to ask: "You have authorized accounts A and B for the US site, which one would you like to use this time?"
accountName - 0 candidates → Inform the user that the site is not authorized, and guide them to complete authorization via .
linkfox-amazon-ads-auth
- Strictly prohibit asking users to directly provide the profileId number.
- Strictly prohibit bypassing clarification by "picking the first one" or "selecting default" when there is ambiguity.
linkfox-amazon-ads-authCore Concepts
- Coverage: All report types of SP / SB (based on the files under
.md; SD / ST / DSP are not covered yet)references/report-types/ - One-stop: The script internally and automatically completes report creation → waiting for generation (about 2–10 minutes) → downloading → decompression; the caller only needs to wait for the final result
- Single script: (covers all adProducts of SP / SB)
get_report.py - Metadata vs. Runtime Parameters:
- Available fields (timeUnit / groupBy / filters / all column names) for each report type are centralized in
references/report-types/<adProduct-dir>/<reportTypeId>.md - Script runtime parameters (polling interval, access link validity, etc.) can be found in this document and
references/api.md
- Available fields (timeUnit / groupBy / filters / all column names) for each report type are centralized in
Available Scripts
| Script | Responsibility |
|---|---|
| One-stop execution. Required parameters |
| Checks if linkfox-amazon-ads-auth is installed |
references/api.mdAgent Calling Flow
- Determine reportTypeId: Select based on user intent (e.g., "last week's spend"→ ; "which products sold well"→
spCampaigns/spAdvertisedProduct; "what terms did users search to find me"→sbPurchasedProduct)spSearchTerm - Check reference: Open
references/report-types/<adProduct-dir>/<reportTypeId>.md- frontmatter provides: /
adProduct(recommended in Configuration table) /groupBy(enumerable) /timeUnit/format/dateRangefilters - Base metrics table provides: all column names allowed for this report type
- frontmatter provides:
- Consult user for customizable conditions (skip if user replies "default/whatever" and proceed to default selection in Step 4):
- : DAILY (split by day) or SUMMARY (aggregated)
timeUnit - extension: Whether to add attribution columns (sales7d / purchases7d / acosClicks7d / roasClicks7d), video metrics, newToBrand, etc.
columns - : Whether to filter campaignStatus / keywordType / adStatus, etc.
filters
- Construct columns based on user reply or default conditions (see "Default Conditions" section below)
- Call the script: Explicitly pass in the three required fields /
adProduct/groupBycolumns
Default Conditions (Used when user does not specify)
| Condition | Default Rule |
|---|---|
| Date range ≤ 7 days → |
| Must include |
| |
| Only add when user mentions intent like "sales/conversion/ROI/ACOS": |
| No filters applied (return full data) |
| Take the first value in the frontmatter |
Request Examples
adProductgroupBycolumns1. SP Campaign Report (Most Common)
python scripts/get_report.py '{
"profileId": 1234567890, "region": "NA",
"reportTypeId": "spCampaigns",
"adProduct": "SPONSORED_PRODUCTS",
"groupBy": ["campaign"],
"columns": ["date","campaignId","campaignName","impressions","clicks","cost"],
"startDate": "2026-04-27","endDate": "2026-05-03",
"timeUnit": "DAILY"
}'2. SP Search Term Report (with Attribution)
python scripts/get_report.py '{
"profileId": 1234567890, "region": "NA",
"reportTypeId": "spSearchTerm",
"adProduct": "SPONSORED_PRODUCTS",
"groupBy": ["searchTerm"],
"columns": ["searchTerm","keyword","matchType","impressions","clicks","cost",
"sales7d","sales14d","purchases7d","acosClicks14d","roasClicks14d",
"startDate","endDate"],
"startDate": "2026-04-01","endDate": "2026-04-30",
"timeUnit": "SUMMARY",
"filters": [{"field":"keywordType","values":["BROAD","PHRASE","EXACT"]}]
}'3. SB Ad Group Report
python scripts/get_report.py '{
"profileId": 1234567890, "region": "NA",
"reportTypeId": "sbAdGroup",
"adProduct": "SPONSORED_BRANDS",
"groupBy": ["adGroup"],
"columns": ["adGroupId","adGroupName","impressions","clicks","cost","purchases","sales","startDate","endDate"],
"startDate": "2026-04-01","endDate": "2026-04-30"
}'4. Poll an Existing reportId (Recover from previous timeout / manual recovery)
reportIdprofileIdregionreportIdpython scripts/get_report.py '{
"profileId": 1234567890, "region": "NA",
"reportId": "7df1ef5d-45ba-40cc-b607-ff2148cf4f5e",
"maxAttempts": 60, "pollInterval": 30
}'Auto-recovery: If the caller does not passand Amazon triggers deduplication for the same parameter request (returns HTTP 425reportId), the script will automatically parse the old reportId and switch to polling that old report, no retry is needed.The Request is a duplicate of : <uuid>
Response Format
{
"success": true,
"reportId": "4ee811a0-...",
"reportTypeId": "spCampaigns",
"startDate": "2026-04-28", "endDate": "2026-05-04",
"downloadPath": "C:/.../tmp/report_data.json",
"extractedFileHttpUrl": "http://127.0.0.1:51234/download",
"extractedFileHttpServeSeconds": 300
}{"error":"Upstream HTTP 400","httpStatus":400,
"body":"{\"code\":\"400\",\"detail\":\"startDate to endDate range (32 days) must not exceed maximum range (31 days)\"}"}Calling Principles
- Only pull the specified reportTypeId if the user has specified it; do not replace it without permission
- When report generation fails (non-2xx or status=FAILED), truthfully inform the user of the error reason; do not retry blindly
- After success, fully display the local file path and access link of the report to the user, and remind them that the access link has a validity period (valid for 5 minutes by default, need to pull again if expired)
- Timeout is not failure: When the script returns (exit code=2), it means the client has waited the default 10 minutes but the report is still being generated on Amazon's side. At this time, must explain the situation to the user and ask if they want to continue waiting; never treat it as a failure. Reference reply: "The report is still being generated on Amazon's side (waited 10 minutes), do you want to continue waiting? You can choose: A. Wait another ~20 minutes (maxAttempts=60), B. Wait another ~1 hour (maxAttempts=120), C. Stop now, I'll come back with the reportId later." If the user selects A/B → use
status=STILL_PROCESSINGto switch to polling-only mode and continue runningresumeHint.params
Common Errors
| Status | Meaning | Suggestion |
|---|---|---|
| Caller did not explicitly pass in the three required parameters | Go back to Step 2 of "Agent Calling Flow", read and supplement the parameters from |
| accessToken expired | Call |
| No associated ad account or insufficient permissions | Check the manager account/ad account association in the Amazon Ads backend |
| Date range exceeds limit (most are 31 days) | Split the pull and merge locally; refer to the frontmatter |
| Column name misspelled / does not match reportTypeId / exceeds Base metrics | Check against the Base metrics table in the |
| Upstream generation failed | Mostly due to date window or permission issues; handle according to the specific failureReason |
| Client polling window exhausted but report is still being generated | Not a failure. stdout already contains |
| A report with the same parameters is already running | The script will automatically parse and switch to polling the old reportId; no intervention is needed from the caller under normal circumstances |
| exit 42 | Dependent skill not installed | Install |
Dates and Data
- Date range limit: Most reports allow 31 days; allows 731 days;
sbPurchasedProduct/spGrossAndInvalids/sbGrossAndInvalidsallow 365 days (refer to frontmatter for details)sdGrossAndInvalids - Lookback window: SP defaults to 95 days, SB defaults to 60 days, GrossAndInvalids defaults to 365 days; refer to frontmatter for details
dateRange.dataRetentionDays - Data delay is about 12 hours; the script will output a warning to stderr but not block if
endDate >= today - Empty data does not equal error: If there is no campaign activity in the account during the period, the report will be generated successfully, and the JSON may be or all metrics are 0
[]
Not Applicable
- Brand Analytics / Retail Analytics / Attribution reports → Not covered by this skill
- Report deletion / modification / scheduled tasks → Not covered by this skill
- Entity metadata (campaign name, keyword match type, etc.) → Handled by
linkfox-amazon-ads-entity - Authorization / token → Handled by
linkfox-amazon-ads-auth
- The functionality or purpose described in this skill does not match actual behavior
- The skill's results do not match the user's intent
- The user expresses dissatisfaction or praise about this skill
- Anything you believe could be improved
references/api.md