Skip to main content

amazon-ads

Amazon Sponsored Products / Sponsored Brands / Sponsored Display ads + Coupons on Seller Central / advertising console. ONE catalog covering BOTH mechanics (URLs, click paths, modal patterns, kat-* component gotchas, field input ranges) AND workflows (tuning existing campaigns, weekly review, search-term harvest, ACOS improvement). Load this skill BEFORE any browser-use action that creates, edits, captures, archives, or downloads campaigns / ad-groups / keywords / product targets / coupons on amazon.<tld> or advertising.amazon.<tld>. The catalog below points to topical references — load whichever ones the task needs. Defaults to last 30 days for tuning analysis but accepts any user-specified window.

Informations de source

Dépôt
zpoint/vibe-seller
Dernière activité de la source
20 septembre 2026 à 06:42
Langue détectée de SKILL.md
anglais
Étoiles
83
Forks
19

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
18 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
amazon-ads
description
Amazon Sponsored Products / Sponsored Brands / Sponsored Display ads + Coupons on Seller Central / advertising console. ONE catalog covering BOTH mechanics (URLs, click paths, modal patterns, kat-* component gotchas, field input ranges) AND workflows (tuning existing campaigns, weekly review, search-term harvest, ACOS improvement). Load this skill BEFORE any browser-use action that creates, edits, captures, archives, or downloads campaigns / ad-groups / keywords / product targets / coupons on amazon.<tld> or advertising.amazon.<tld>. The catalog below points to topical references — load whichever ones the task needs. Defaults to last 30 days for tuning analysis but accepts any user-specified window.
allowed-tools
Bash(browser-use:*)
requires
["amazon-shared"]
gates
["ad_change_cooldown","ad_completeness_review","ad_negation_allowlist","ad_execution_fidelity","ad_writeback_backing"]
# Amazon Ads — Catalog > **PREREQUISITE:** Read `../amazon-shared/SKILL.md` for marketplace > TLD map, version-aware navigation (New Seller Central vs classic; > navigate by direct URL), the Ziniao login challenge-loop (password / > OTP / hosted-passkey), > and the ad-console vs seller-central account caveat. ## 0. FIRST — declare what this task is for **Before any browser action, call `vibe_seller_declare_ad_task`.** This is a precondition, not a courtesy: a report with no declaration behind it is refused. Two things follow from the declaration and cannot be changed afterwards — how much the completeness gate asks of you, and whether the user gets a review console. Read them off what the person actually asked for, not off what you expect to find once you look. | They asked for | `kind` | `scope` | |---|---|---| | "审计一下广告" / "review our ads" | `audit` | omit `combos` — whole store | | "复核 widget-006 在 amazon 的广告" | `audit` | that platform+country, those campaign ids | | "把这三个词的出价降下来" | `audit` | those campaigns | | "帮 widget-006 建关键词广告" | `create` | the market you are creating in | | "执行刚才确认的调整" | `execute` | the campaigns being changed | | "我们 SA 的 ACOS 大概多少" | `investigate` | the market asked about | **Numbers or changes?** That is the line between `investigate` and `audit`, and it matters more than the table above. If the answer the person wants is a FIGURE — what did we spend, what is our ROAS, how did last month go — that is `investigate`, however many markets it spans: you are reading, not proposing. If they want to know what to CHANGE, or asked "is this right?", that is `audit`, and it opens a review console. Observed live: a plain "how much did we spend on ads this month, and what came back?" was declared a whole-store `audit`, which put five marketplaces of drill work behind a question that wanted four numbers. And the other way round, observed in CI: "review the keyword bids on <campaign>" was declared `investigate`, so the bid recommendations it produced reached the user with no console to approve them on. **If you got it wrong, correct it upward.** If you declared `investigate` and the work turned out to produce decisions — a table telling someone to raise, cut, pause or negate — call `vibe_seller_declare_ad_task` again with `kind: "audit"` and the same scope, or a narrower one. That is the ONLY kind change allowed inside a turn, and it is allowed because it only ever makes you owe more: the coverage obligation appears and the user gets the console. Going the other way (`audit` → `investigate`), adding a marketplace, or widening the campaign list are all still refused, and still need a new message from the user. Do not instead delete your recommendations to fit the declaration — the person asked what to change. **There is no `edit` kind.** A request to change specific bids is an `audit` whose scope names those campaigns — the user still reviews the change before it is applied, and the scope is what makes it small. **The scope trap:** omitting `combos` means EVERY marketplace this store sells on, and you will be held to all of them. Omit it only when the request really is store-wide. A store selling on five marketplaces has been asked for all five because a one-product task left the field out. **If the request names a product, not a campaign** ("widget-006 的广告"), declare the MARKET now and the campaigns later. You cannot know campaign ids before you have looked, and declaring a market with no campaign list means **every campaign in it** — which is how a one-product request turns into an audit owing a whole marketplace. So: declare `{kind, combos, products}` first, enumerate the campaign list, find the campaigns carrying that SKU family, then call the tool AGAIN with the same kind and the same combos plus `campaigns: [...]`. That second call is a **narrowing refinement** and is accepted within the same turn. **Refining may only ever remove reach.** Same kind, same marketplaces, and a campaign list going from "all of them" to a named subset. You cannot add a marketplace, change the kind, or widen the campaign list — a wider scope needs a new message from the user. If a gate asks for something outside your scope, say so in your result and let the user redirect you; do not try to re-declare around it. **When the user sends a NEW message that changes what you are doing, declare again.** That is a new phase, and it is the only way a declaration changes. Two cases you will hit often: - "现在把刚创建的广告复核一下" after a `create` phase → declare `audit`, and its scope may name the campaigns you created earlier in this same task. - The review console submits the user's decisions back as a follow-up message → declare `execute`, scoped to the campaigns that submission actually names. --- This skill is a **catalog**. The actual content lives in topical references in `references/`. Load whichever ones apply to the task. ## When something doesn't fit the recipe — recover, don't stall The references below are worked examples, not the full space of what you'll hit. Amazon's UI, campaign types, and account states vary; a step that assumes one shape will sometimes meet another. **A gap in these docs is not a stop sign — it's a cue to reason from first principles.** You are a capable agent; the recipe is a starting point, not a cage. When a documented step doesn't fit, do NOT hand a half-finished task back to the user ("please do X manually"). Work the problem: - **The export is ground truth; the live UI is fragile.** For anything data-heavy — reading campaigns, keywords, search terms, deciding what to negate — use the **bulk export** (or a Search-Terms CSV), never the on-screen grid. Amazon's grids are **virtualized** (only ~13 of hundreds of rows exist in the DOM; `innerText` is undefined mid-scroll). Scraping them is the single most common way a run wastes itself. If you catch yourself scrolling a grid and re-reading, stop — export instead. - **The grid's OWN inline "导出 / Export" button is a PAGE-SCOPED trap — it is NOT the bulk export.** On the Campaign Manager grid the Export control opens a menu whose "当前表格数据 / current table data → 下载 / Download" option dumps **only the ~50 rows on the current grid page**, not the account. It looks exactly like "the export," so trusting it is the single most common way a run under-counts a large account — **verified live: it returned 50 of 146 campaigns, and the grid's own "下一页 / Next Page" then silently refused to advance (JS click returns `clicked:false`; the grid virtualizes), trapping the run at page 1.** Do **NOT** enumerate by paging the grid or by its inline Export. The account-wide export is the **Bulk Operations download** (`mechanics.md` §2d) — one XLSX covering every campaign regardless of grid pagination (reuse the newest `bulk-*.xlsx` first). **After any download, verify its campaign-row count equals the grid's `aria-rowcount`; if it's ~50 (one page), you grabbed the page-scoped file — discard it and use Bulk Operations.** A file whose count ≠ the grid total is not the account. - **A persisted search/status filter silently hides campaigns — clear it FIRST, and trust the grid's own total, not a scraped row count.** The Campaign Manager's campaign-search box keeps whatever term was last typed (stored in the browser profile, not the URL), so it stays applied when you open the list and can show a small fraction of a much larger account. **Before enumerating, if the campaign-search input has a non-empty value, campaigns are hidden — clear it.** Three traps make this the most common under-count cause, all verified live: - **The list-level "clear filters" / "remove all" control does NOT clear it** — that only drops the status/type filter *chips*; the search term survives. - **Setting the input `.value` does NOT clear it** — the field is React-controlled: it re-applies the old filter, and a `value===''` check then *falsely* passes ("false-cleared"). - **A synthetic `dispatchEvent` click on the ✕ does nothing** — the widget only honors a *trusted* pointer event. **What works: a REAL coordinate click (`click_at_xy`) on the search box's own clear ✕** — locate it by the aria-label `Clear search terms` (aria-labels stay English even on a localized UI; the visible placeholder/footer text does not, so never key on that). Then read the grid's **`aria-rowcount`** (language-neutral; the full filtered total, not the ~13 virtualized DOM rows) — a real clear makes it jump. **A suspiciously low total = a filter still applied; do not report it.** Also clear the default status filter so paused/archived campaigns count. Amazon ships more than one console layout — the exact selectors are the common ag-grid case, but the invariant holds on all of them: trust the grid's own total over any DOM scrape. Snippet + fallbacks: [`mechanics.md`](references/mechanics.md) §2a (**load it before your first campaign-list read**). - **Data is scoped to whatever marketplace the console is showing — so a country's absence is never proof it's empty.** Amazon's ad console comes in more than one shape, and you must not assume which you're on: - *Per-country account* — the console shows **one marketplace at a time**, selected by the top-left `Sponsored ads, <Country>` control; each country is a **separate account/entity** (the brand name can even differ per market). The list — and a bulk export — cover only the selected country. - *Unified multi-market entity* — a **single list spans several countries**, distinguished by a Country column, and the export may carry a marketplace/country column covering all of them. Don't guess which you have — **check**: does the current view (or the switcher menu) actually name the country you were asked about? Is there a per-row Country column, and does the export contain that country's rows? The invariant, true in every shape: **confirm each requested country is actually represented in the data you read.** If a country isn't present, it lives behind the switcher (or under another entity) — go get it; do **not** conclude it has no ads. When the user asks about more than one country (or "all", or one the console isn't currently showing) and the layout is per-country, **switch to each country and export separately** — one download per country — then compare. To prove any negative ("no ads in X"), put X in view and look. A stored note claiming a market is empty is a stale per-run snapshot, not a fact — re-verify it live before you trust it. - **If a command/recipe doesn't cover your case, build it from the export's own structure.** `ads_bulk.py` has `inspect` / **`scope`** / `clone-campaign` / `bid-update` / `negate` / `archive-campaign` — check this list before hand-parsing the workbook; `scope` in particular already emits the `state=enabled` id set plus its independently-counted total, which is exactly what `AUDIT_SCOPE.json` needs, so re-deriving it with openpyxl is wasted work. But if your case isn't one of them (a campaign type, an entity, a field with no helper), open the export, find a row of the kind you need (a working example of exactly this on this account), and emit the same columns with your values changed. The export **teaches you the exact tokens** this account+locale accepts — you never have to invent them. (Worked: an SB-video negative isn't in the SP script, so read an SB row and build the SB negative sheet from it.) - **Poll async jobs in separate, short calls — never one long silent sleep, and never block on a Monitor for browser/job state.** A bulk export or upload takes minutes; check it with a short poll (a few `sleep 20` + re-open), returning to the loop between checks so progress stays observable. A single 15-minute `sleep` — or blocking a `Monitor`/`TaskOutput` waiting for a page/job event — looks like a hang and strands the run. - **Verify by re-reading ground truth, not by trusting "Success".** A bulk `Success` status only means the file was accepted; re-export (or re-read the campaign) and confirm the committed state — the campaign is `enabled`, the Product Ad advertises the *intended* SKU (a cloned campaign renamed to the new product can still point at the old SKU), the negatives are present. - **Never exit-in-the-half.** If you're blocked, restate the invariant ("I must end this campaign as `enabled` advertising SKU X"), find the ground-truth source, and take the next concrete step toward it. Ask a human only when a credential/permission is genuinely missing, not when a recipe merely ran out. The references are the map; these principles are how you travel when the map ends. ## What this skill produces For tuning / audit tasks ("review the ads", "improve ACOS", "audit"): **one Markdown report** (`AD_AUDIT_<YYYY-MM-DD>.md`) + **two TSVs per active campaign** (`stores/<slug>/ads/<platform>/<country>/<id>.tsv` targets + `<id>.searchterms.tsv` full customer-query set). Every campaign is drilled in TWO layers on the same date window — targets AND search terms — proven by a `搜索词对账` reconciliation line the server reviewer parses. **START HERE — do NOT pre-read every reference (it buries the model and causes shortcutting). Just two files, then run:** 1. **[`output-spec.md`](references/output-spec.md)** — the report contract (what "done" looks like). 2. **[`audit-quickref.md`](references/audit-quickref.md)** — the entire procedure on one page. Load a heavy reference only when a step there tells you to. Write the report to `AD_AUDIT_<YYYY-MM-DD>.md`, and persist the authoritative active-campaign ids per marketplace to `AUDIT_SCOPE.json` (run `python3 .claude/skills/amazon-ads/scripts/ads_bulk.py scope <each market's export>` — your CWD is the task workspace, so the script must be addressed through the synced skill path) — the coverage floor checks against it. **What you owe is what you DECLARED.** `AUDIT_TARGETS.json` at the task root lists every marketplace the store is configured for — it is the MENU, written by the server from Settings, not your inference and not a market list in the task description (prose goes stale when a store gains a marketplace). Your `vibe_seller_declare_ad_task` call is what turns part of that menu into an obligation: * declared `combos` → you owe exactly those, each with an `AUDIT_SCOPE.json` entry AND a `## <Platform> <Country>` report section, even one with no live campaigns (`"active_ids": []`, `"total_active": 0`); * declared NO `combos` (a whole-store audit) → you owe every combo in `AUDIT_TARGETS.json`, same rules. Do NOT expand past your declaration because the menu is longer. A user who asked about one marketplace gets one marketplace; auditing the other four is work nobody asked for, and reporting on them is a `[基线]` out-of-scope gap. If you believe the scope is wrong, say so in your result and let the user widen it — you may not widen it yourself. **Before `vibe_seller_set_task_result`, you MUST pass verification — the report is not done until it's checked against the live console:** 1. The server's **coverage floor** (deterministic): every marketplace enumerated, every active id drilled, drills never regress. It replies with "what's still missing"; fix and re-submit until clean. 2. The **`ads-report-review` reviewer loop** (active verification): spawn the reviewer subagent per [`reviewer-loop.md`](references/reviewer-loop.md) — it **opens the live console / re-exports and cross-checks your report against reality** (samples your claimed drills, switches to any "empty" marketplace to confirm, rejects count/category summaries that aren't word-level). Fix the gaps it writes, re-run it, until it writes `Status: ok`. The Stop-hook will not let you finish until it does. Both must pass. This is how "done" is defined for an ad report: verified against the live console, drilled to the word level — never a claim. **Then submit the FILE**: `vibe_seller_set_task_result("./AD_AUDIT_<date>.md")` — the path, never a chat summary of the report. The reviewer grades whatever string you pass it, and a summary has no `##` combo sections to grade. ## Workflow references — the "what to do" thinking | Reference | Load when | |---|---| | [`output-spec.md`](references/output-spec.md) | **Read first for every audit.** The report contract the server completeness reviewer checks against — per-(platform,country) 进度 line, header table, per-campaign drills, the 4 bid rules, TSV-per-campaign. | | [`audit-quickref.md`](references/audit-quickref.md) | **The procedure, one page.** Run this top-to-bottom; it points to heavy refs on demand. | | [`format-anchor.md`](references/format-anchor.md) | _Legacy detail._ Per-campaign table column shape; load only if you need the exact table layout. (The mandatory subagent reviewer-loop is superseded by the server completeness reviewer — partial is accepted, it lists gaps each round.) | | [`reviewer-loop.md`](references/reviewer-loop.md) | **Required before finishing ANY ad report.** Phase-3 `ads-report-review` = active verification (opens the live console/export, cross-checks your report, loops until `Status: ok`; Stop-hook enforced). Phase-4 `ads-execution-review` for apply tasks (`EXEC_REVIEW_*`). | | [`tuning-workflow.md`](references/tuning-workflow.md) | User asks to tune ads, improve ACOS, "review last month's ads", harvest search terms, lower bids on losers, weekly ad review, "why is X campaign burning money", or any ongoing-campaign refinement task. | | [`tuning-campaign-types.md`](references/tuning-campaign-types.md) | A campaign isn't SP-Manual-Keyword. The skill defaults to SP-Manual-Keyword; for SP-Auto / SP-Manual-Product / Sponsored Brands / Sponsored Brands Video / Sponsored Display, this reference has the per-type sidebar tabs, Targeting-tab columns, and lever-applicability matrix observed on a live merchant account. Pair with `tuning-workflow.md` Phase 3 — that phase branches on type. | | [`tuning-thresholds.md`](references/tuning-thresholds.md) | Need to derive per-store thresholds (breakeven ACOS = margin %, target ACOS = 0.7 × breakeven, protect-zone, waste/harvest cutoffs). Always heuristic, never hardcoded. | | [`tuning-toolbox.md`](references/tuning-toolbox.md) | Picking the right lever — 8 levers + 2 advanced (dayparting, structural splits) disabled by default. Ordered surgical-first (search-term negate / harvest, per-keyword bid trim) → blanket-last (bidding strategy, pause campaign). For which levers apply per type, see `tuning-campaign-types.md`. | | [`tuning-funnel-diagnosis.md`](references/tuning-funnel-diagnosis.md) | Distinguishing listing-side problems (low CTR = image / title; low CVR = PDP / price / reviews) from ad-side problems (ACOS) before reaching for a bid lever. Bad CTR is not an ad-tuning problem. | | [`tuning-recommendation-format.md`](references/tuning-recommendation-format.md) | Composing the per-campaign output table at the end of a tuning session — header table → per-campaign data → per-problem subsections with per-entity data tables. Targeting-first, placement-second. Data table shape varies by type — see `tuning-campaign-types.md`. | | [`tuning-history.md`](references/tuning-history.md) | The per-campaign TSV under git that records every observed state (bid, status, suggested range, recent metrics) across audits. Read at Phase 2 to diff scrape against record (catches OBSERVED_DRIFT); read at Phase 3 for recency check before recommending changes (< 7 days since last change → downgrade to Hold); written at Phase 4 after each verified apply (cause-and-effect ledger). One TSV per campaign, written via `vibe_seller_write_workspace_file`; the workspace auto-commits. | ## Mechanics reference — the "how to click" lookup | Reference | Load when | |---|---|
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub