Amazon Ads ad management skill, supporting list (query) and create / update (create and modify) operations; via developerProxy pass profileId, the server parses the token (do not first storeTokens get the raw token). Automatically handles pagination and filter field normalization.
| Ad product | Covered entities | Script subdirectory | Detailed parameters |
|---|---|---|---|
| SP (Sponsored Products) v3 | campaigns / adGroups / keywords / negativeKeywords / productAds / targets | scripts/sp/ |
references/api/sp.md |
| SB V3 Legacy + V4 | V3 Legacy campaigns/keywords/targets; V4 campaigns/adGroups/ads/creative versions; keywords/targets go through the V4 script entry point but underneath use the shared targeting path | scripts/sb/v3/、scripts/sb/v4/ |
references/api/sb.md |
| SD (Sponsored Display) v3 | campaigns / adGroups / productAds / targets / negativeTargets / creatives | scripts/sd/ |
references/api/sd.md |
Depends on linkfox-amazon-ads-auth(automatically checked at script startup; if not installed, exit 42, stderr prints DEPENDENCY_MISSING)。
⚠️ Multi-account scenario: profileId must be resolved before calling
Users often only speak in natural language ("US site", "Japan site", "my store"); all scripts in this skill must obtain the numeric profileId before they can be called. Handle in the following order,do not skip:
- First call
linkfox-amazon-ads-auth'sauthorized_stores.pyto pull the list of accounts × marketplaces the user has authorized. - Based on the marketplace mentioned by the user (mapped to
countryCode, e.g. US→US) match candidate profiles:- Only 1 candidate → silently take the corresponding profileId and continue the call; do not announce the profileId number to the user.
- ≥ 2 candidates (multiple authorized accounts under the same marketplace) → must clarify with the user, use
accountNameto ask: "You have authorized two accounts, A and B, on the US site. Which one should be used this time?" - 0 candidates → inform the user that this marketplace is not authorized, and guide them to
linkfox-amazon-ads-authto perform authorization.
- Strictly prohibitedto let the user directly report the profileId number.
- Strictly prohibitedunder ambiguity to "pick the first one" or "choose the default" to bypass clarification.
For the complete decision table, see linkfox-amazon-ads-auth SKILL.md's Usage Scenarios Section 4。
Core Concepts
- Automatic pagination:
fetchAll=true(default) follows pagination to the end ormaxPages=50fallback; SP and SB V4 main resource list usenextToken, SB Target/BudgetRule usenextToken(BudgetRule queries must includepageSize), SB Keyword GET, SB V3 GET and SD usestartIndex + count - Filter structures are not unified: different fields require different formats (see "Filter Structure Quick Reference" below); this skill already performs automatic fallback normalization for common incorrectly formatted inputs, but it is still recommended to pass them accurately according to the quick reference table
- Only metadata is provided, no metrics: returns entity fields (id / name / status / match type, etc.); metrics such as impressions / clicks / spend / conversions require calling
linkfox-amazon-ads-report, joined by id - Supports create / update: under each module
create_*.py/update_*.pyscripts create or modify entities (campaign / adGroup / keyword / target / productAd / budgetRule), payload is passed through in Amazon native format; SB Creative only supports byadIdQuery Creative Version and create a new version; there is no generic update script - SB V3/V4 coexistence: by default use
scripts/sb/v4/; use only when it is confirmed to be Legacy or the user explicitly requests V3scripts/sb/v3/. Do not automatically perform V4→V3 fallback; known Multi-Ad-Group Campaigns must reject V3 - SB shared Targeting: Amazon's Keyword/Target still uses
sb/keywords、sb/targets[/list], there is no fabricated/sb/v4/keywords; the V3/V4 script entry points are isolated, but the underlying shared official targeting resources are used - SD interface form: Sponsored Display is a v3 REST endpoint,
GET /sd/<entity>+ querystring, pagination usesstartIndex + count; state / id type filters are comma-separated strings; whenincludeExtendedDataFields:truerequest the/sd/<entity>/extendedpath. All filter fields uniformly support the{"include":[...]}input parameter
Available scripts
SP (28)
| Script | Business entity | Operation |
|---|---|---|
sp/list_campaigns.py |
Campaign | Query |
sp/create_campaigns.py |
Campaign | Create |
sp/update_campaigns.py |
Campaign | Modify (budget/strategy/status/name, etc.) |
sp/list_ad_groups.py |
Ad group | Query |
sp/create_ad_groups.py |
Ad group | Create |
sp/update_ad_groups.py |
Ad group | Modify (default bid/status/name, etc.) |
sp/list_keywords.py |
Keyword | Query |
sp/create_keywords.py |
Keyword | Create |
sp/update_keywords.py |
Keyword | Modify (bid/status, etc.) |
sp/list_negative_keywords.py |
Negative keyword | Query |
sp/create_negative_keywords.py |
Negative keyword | Create |
sp/update_negative_keywords.py |
Negative keyword | Modify (status, etc.) |
sp/list_product_ads.py |
Product ad | Query |
sp/create_product_ads.py |
Product ad | Create |
sp/update_product_ads.py |
Product ad | Modify (status, etc.) |
sp/list_targets.py |
Product targeting | Query |
sp/create_targets.py |
Product targeting | Create |
sp/update_targets.py |
Product targeting | Modify (bid/status, etc.) |
sp/create_campaign_negative_keywords.py |
Campaign-level negative keyword | Create |
sp/update_campaign_negative_keywords.py |
Campaign-level negative keyword | Modify (status, etc.) |
sp/create_campaign_negative_targets.py |
Campaign-level negative targeting | Create |
sp/update_campaign_negative_targets.py |
Campaign-level negative targeting | Modify (status, etc.) |
sp/create_negative_targets.py |
Ad group-level negative targeting | Create |
sp/update_negative_targets.py |
Ad group-level negative targeting | Modify (status, etc.) |
sp/list_budget_rules.py |
Budget rule | Query |
sp/create_budget_rules.py |
Budget rule | Create |
sp/update_budget_rules.py |
Budget rule | Modify |
sp/create_budget_rules_association.py |
Budget rule association | Associate rule with campaign |
SB V3 Legacy (10)
| Script group | Business entity | Operation |
|---|---|---|
sb/v3/list/create/update_campaigns.py |
Legacy campaign (Creative embedded) | Query/Create/Modify |
sb/v3/list_ad_groups.py |
Legacy ad group | Query |
sb/v3/list/create/update_keywords.py |
Keyword | Query/Create/Modify |
sb/v3/list/create/update_targets.py |
Product targeting | Query/Create/Modify |
V3 is only compatible with Legacy. If the parameters include campaignStructure:"MULTI_AD_GROUP" or isMultiAdGroupsEnabled:true, the script returns SB_V4_CAMPAIGN_NOT_SUPPORTED. The script has no local Campaign database, so before calling it you should first use V4 Campaign list to confirm the structure.
SB V4 (20)
| Script group | Business entity | Operation |
|---|---|---|
sb/v4/list/create/update_campaigns.py |
Campaign | Query/Create/Modify |
sb/v4/list/create/update_ad_groups.py |
Ad group | Query/Create/Modify |
sb/v4/list/create/update_ads.py |
Ad | Query/Create/Modify |
sb/v4/list/create/update_keywords.py |
Keyword (Amazon shared targeting path sb/keywords) |
Query/Create/Modify |
sb/v4/list/create/update_targets.py |
Product targeting (Amazon shared targeting path sb/targets[/list]) |
Query/Create/Modify |
sb/v4/list_creatives.py、create_creatives.py |
Independent Creative Version | By adId Query/Create new version |
sb/v4/list/create/update_budget_rules.py |
Budget rule | Query/Create/Modify |
Original scripts/sb/*.py continues to serve as a compatibility entry point for existing V4 operations (thin wrapper forwarding to scripts/sb/v4/); new calls should uniformly use the versioned directory. For complete rules, see references/api/sb-coexistence.md。
SD (21)
| Script | Business entity | Operation |
|---|---|---|
sd/list_campaigns.py |
Campaign | Query |
sd/create_campaigns.py |
Campaign | Create |
sd/update_campaigns.py |
Campaign | Modify (budget/status/name, etc.) |
sd/list_ad_groups.py |
Ad group | Query |
sd/create_ad_groups.py |
Ad group | Create |
sd/update_ad_groups.py |
Ad group | Modify (bid/status, etc.) |
sd/list_product_ads.py |
Product ad | Query |
sd/create_product_ads.py |
Product ad | Create |
sd/update_product_ads.py |
Product ad | Modify (status, etc.) |
sd/list_targets.py |
Targeting clause | Query |
sd/create_targets.py |
Targeting clause | Create |
sd/update_targets.py |
Targeting clause | Modify (bid/status, etc.) |
sd/list_negative_targets.py |
Negative targeting clause | Query |
sd/create_negative_targets.py |
Negative targeting clause | Create |
sd/update_negative_targets.py |
Negative targeting clause | Modify (status, etc.) |
sd/list_creatives.py |
Creative asset | Query |
sd/create_creatives.py |
Creative asset | Create |
sd/update_creatives.py |
Creative asset | Modify (asset/status, etc.) |
sd/list_budget_rules.py |
Budget rule | Query |
sd/create_budget_rules.py |
Budget rule | Create |
sd/update_budget_rules.py |
Budget rule | Modify |
| For detailed filters, enum values, and return fields, see references/api/sp.md / references/api/sb.md / references/api/sd.md。 |
How to call
- API endpoint:
POST /amazonAds/developerProxy(different operations are distinguished by the request body; for complete parameters/responses/error codes, seereferences/api.md) - Python script:
python scripts/<脚本名>.py '<JSON 参数>' [--inline]; new SB calls must explicitly usescripts/sb/v3/orscripts/sb/v4/ - Cost constraints: This tool consumes compute; on failure/empty results, do not automatically switch keywords, paginate, or repeatedly probe; if you need to continue searching, first explain to the user that additional consumption will be incurred.
Output strategy (default script behavior):
- Alwayswrite the full response to
<cwd>/linkfox/<YYYY-MM-DD>/<session>/data/linkfox-amazon-ads-manager-<timestamp>.json(<cwd>is the working directory when the script executes, which in Claude Code is the current project directory;<session>is taken from the environment variableSESSION_ID, automatically aggregated according to the user task;writing to /tmp is prohibited, if the current directory is not writable, report an error) - Response body ≤ 8 KB: after saving to disk, print the complete JSON to stdout
- Response body > 8 KB: after saving to disk, stdout outputs only a summary (top-level fields, common counts such as
total/costToken, the length of the largest list field + first 3 samples) - Add
--inlineto force full printing to stdout (also save to disk)
Data reading recommendations: first look at the summary to determine whether it is sufficient; when specific fields are needed, prioritize using jqorConvertFrom-Json to extract on demand from the saved json file, avoiding bringing the entire JSON into the context.
Resolve authentication and compute issues
When the following abnormal situations occur, use references/onboarding.md to guide resolution:
Abnormal situations
- API Key not configured: the environment variable is not configured
LINKFOX_AGENT_API_KEY, andLINKFOXAGENT_API_KEY。 - Response 401 or 402 status code
- Response indicates insufficient compute or balance: the message contains "insufficient compute balance/insufficient billing/insufficient balance/quota exceeded/insufficient balance/package expired/recharge required/please recharge", or content with a similar meaning.
Financial Safety Guidance
Create and update operations may directly affect ad spend, take effect immediately, and cannot be undone.
Decision rules:
| User status | Agent behavior |
|---|---|
| Authorized (has said "automatic bid adjustment"/"go with your judgment"/"no need to ask me"/"confirm", etc.) | Execute directly → output operation receipt |
| Not authorized (first interaction, no explicit stance) | First output a confirmation summary → execute after user confirmation |
Confirmation summary template(when not authorized, output before execution):
📋 即将执行:
- 操作:[创建/修改] [N 个] [实体类型]
- 变更:[关键字段变化,如 bid $1.0→$1.5 / budget $50→$100]
- 影响:[花费变化预估,引用日预算作为上限]
确认执行?后续如需自动处理,告诉我即可。
Operation receipt template(must be output after each write operation is executed):
✅ 已执行:[简短描述]
- 范围:[实体数量、名称或 ID]
- 变化:[具体变更内容]
- 结果:[成功 N 个 / 失败 M 个]
Shared parameters (applicable to SP + SB + SD)
| Field | Type | Description |
|---|---|---|
profileId |
number | Required, obtained from ads-auth |
region |
string | Required,NA / EU / FE |
fetchAll |
bool | Default true; SP and SB V4 main resource list use nextToken, SB Target/BudgetRule use nextToken(BudgetRule queries must include pageSize), SB Keyword GET, SB V3 GET and SD use startIndex + count |
maxResults |
int | 1-100, default 100; corresponds to the Sponsored Display side count |
includeExtendedDataFields |
bool | returns extended fields (some entities); SD switches via the path to /sd/<entity>/extended to implement |
locale |
string | Localization (supported by SP keywords) |
Filter structure quick reference (most error-prone)
| Structure | Example | Applicable fields |
|---|---|---|
| Object | {"include":[...]} / {"exclude":[...]} |
All id/state types: campaignIdFilter, adGroupIdFilter, keywordIdFilter, stateFilter, portfolioIdFilter, expressionTypeFilter, adIdFilter |
| Array | ["EXACT","BROAD"] |
matchTypeFilter(SP keywords/negativeKeywords) |
| Scalar | "AUTO" |
campaignTargetingTypeFilter(SP adGroups) |
| Text | {"queryTermMatchType":"BROAD_MATCH","include":["..."]} |
nameFilter、keywordTextFilter |
| Client | Any form, filtered locally by this skill | asinFilter、skuFilter(SP productAds) |
Common pitfalls:
- SP
matchTypeFilterisa bare array["EXACT"](if passed incorrectly, this skill normalizes it automatically) expressionTypeFilteris instead Object(different from matchType)asinFilter/skuFilterclient-side filtering, it is recommended to also passcampaignIdFilter/adGroupIdFilterto narrow down
Response format
{
"success": true,
"apiVersion": "V3 | V4",
"amazonResourceVersion": "V4 | V3_SHARED_TARGETING | SHARED_TARGETING | SHARED",
"<entityKey>": [ /* 实体数组,字段原样 */ ],
"total": 157,
"pagesFetched": 2,
"truncated": false
}
SB's apiVersion indicates the call entry point/structural intent,amazonResourceVersion indicates the actual Amazon resource version; the two being different does not mean an automatic fallback occurred. When client-side filtering SP productAds, additionally include:serverTotalBeforeClientFilter + clientSideFilters。
Usage examples
1. List active SP campaigns
python scripts/sp/list_campaigns.py '{"profileId":1234567890,"region":"NA",
"stateFilter":{"include":["ENABLED"]}}'
2. View the ad groups under a certain SP campaign
python scripts/sp/list_ad_groups.py '{"profileId":1234567890,"region":"NA",
"campaignIdFilter":{"include":["998877665544"]}}'
3. Look up SP targeting by ASIN (client-side filtering)
python scripts/sp/list_product_ads.py '{"profileId":1234567890,"region":"NA",
"asinFilter":{"include":["B01ABCDEFG"]},
"campaignIdFilter":{"include":["998877665544"]}}'
4. List SB V4 campaigns (default)
python scripts/sb/v4/list_campaigns.py '{"profileId":1234567890,"region":"NA",
"stateFilter":{"include":["ENABLED"]}}'
5. List adGroups / ads under a certain SB V4 campaign
python scripts/sb/v4/list_ad_groups.py '{"profileId":1234567890,"region":"NA",
"campaignIdFilter":{"include":["1122334455"]}}'
python scripts/sb/v4/list_ads.py '{"profileId":1234567890,"region":"NA",
"adGroupIdFilter":{"include":["5566778899"]}}'
6. Manage keywords for an SB V4 campaign (shared targeting path)
python scripts/sb/v4/list_keywords.py '{"profileId":1234567890,"region":"NA",
"campaignIdFilter":["1122334455"],"adGroupIdFilter":["5566778899"]}'
7. Query a confirmed V3 Legacy campaign
python scripts/sb/v3/list_campaigns.py '{"profileId":1234567890,"region":"NA",
"campaignStructure":"LEGACY","stateFilter":["enabled","paused"]}'
8. List active SD campaigns
python scripts/sd/list_campaigns.py '{"profileId":1234567890,"region":"NA",
"stateFilter":{"include":["ENABLED"]}}'
9. Look up SD targeting by ASIN (client-side filtering, with campaign narrowing)
python scripts/sd/list_product_ads.py '{"profileId":1234567890,"region":"NA",
"asinFilter":{"include":["B01ABCDEFG"]},
"campaignIdFilter":{"include":["998877665544"]}}'
10. Analyze metrics together with report
This skill returns entitymetadata(id, name, state, match type, etc.); metrics (impressions, clicks, spend, conversions) are handled by linkfox-amazon-ads-report(reportTypeId: "spTargeting" / "sbCampaigns" / "sdCampaigns" , etc.), joined by id.
Calling principles
- Returned fields are kept as-is; do not rename, translate, or add computed derived metrics
- Do not automatically retry on non-2xx; keep
httpStatus+bodyand inform the user truncated=true, clearly indicate that data retrieval is incomplete
Common errors
| Status | Meaning | Suggestion |
|---|---|---|
HTTP 401 |
accessToken expired | Call ads-auth's refresh_token.py then retry |
HTTP 403 |
profileId has no permission | Verify profileId ownership |
HTTP 400 |
Input parameter structure error | First check the "Filter structure quick reference" table |
HTTP 429 |
Rate limiting | Wait 2-5s and retry |
| exit 42 | Dependency skill not installed | Install first linkfox-amazon-ads-auth |
Not Applicable
- Delete / archive → this skill does not support DELETE (archiving can be achieved by updating state to ARCHIVED, but archiving is irreversible)
- SB does not support downgrading a V4 Multi-Ad-Group Campaign to V3; standalone V3 Creative CRUD does not exist, Legacy Creative is managed through the Campaign payload
- SB negativeKeywords / negativeTargets / themes / recommendations and Legacy→V4 Migration are temporarily out of scope for this A+B+C
- SD's single-query-by-id / brandSafety / recommendations / forecasts / optimizationRules / locations and other "non-basic entity" interfaces → not in this skill
- DSP / ST entities → not in this skill
- Metric reports →
linkfox-amazon-ads-report - Authorization / token / profile →
linkfox-amazon-ads-auth
Amazon Ads API interface protection and retry guidance
When the same advertising account/profile continuously receives 400, 403, 404, or 429 from the Amazon Ads API, the gateway returns 450, 453, 454, or 459 and briefly cools down. These custom status codes are not native Amazon statuses and do not indicate account suspension; the purpose is to avoid continuous anomalies or high-frequency calls increasing the risk to the advertising account.
| Status and message | Scope | Trigger and cooldown | Handling |
|---|---|---|---|
450:400,请求异常,请优化您的参数 |
Advertising account/profile + endpoint | More than 3 times within 60 seconds: 5 minutes; more than 4 times within 10 minutes: 20 minutes | Stop retrying with the original parameters; check profileId, region, entity/report ID, date, and request body |
453:403,店铺未授权,请先授权 |
All endpoints for the advertising account/profile | More than 2 times within 60 seconds: 5 minutes; more than 4 times within 10 minutes: 30 minutes | Stop calls for that advertising account; check Ads authorization, app permissions, profile ownership, and region |
454:404,资源不存在,请优化您的参数 |
Advertising account/profile + endpoint | More than 3 times within 60 seconds: 5 minutes; more than 4 times within 10 minutes: 30 minutes | Confirm the resource ID, the profile/region it belongs to, the resource status, and the endpoint path |
459:429限流中,请降低频率 |
Advertising account/profile + endpoint | First time: 15 seconds; more than 2 times within 2 minutes: 30 seconds; more than 4 times within 3 minutes: 2 minutes | Reduce concurrency, pagination, and polling frequency, and back off progressively |
- Stop automatic or concurrent retries immediately; do not bypass the protection by switching scripts or repeatedly creating tasks; prioritize following
retryAfter、blockedUntil, and when there is none, follow the duration description in the table. - For 450/453/454, the parameters, authorization, or resource identifiers must be corrected first; after the cooldown, retry cautiously at most once; if triggered again, stop calling. During 453, stop all Ads API for that advertising account/profile.
- Keep existing
reportIdand other task IDs; when the result of a write operation is uncertain, query the status first and do not directly replay. - First explain the advertising account protection to the user, then provide the cause, handling, and wait time. You can reply: "To protect the security of your Amazon advertising account, continuous returns of {cause} from the Amazon Ads API have been detected, and a brief protection period is currently in effect. Please first {handling action}, and try again after an estimated {wait time}; this does not mean the account is suspended, nor is it a plan or credit limit." Do not only say "LinkFox rate limiting" or "server busy".
Compute consumption rules
No compute is consumed.
Feedback:
Auto-detect and report feedback via the Feedback API when any of the following apply:
- 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
Call the feedback API as specified in references/api.md. Do not interrupt the user's flow.
For more high-quality, professional cross-border e-commerce skills, visit LinkFox Skills.