Find wasted Amazon ad spend with one prompt and 40 lines of Python
SellerMate Team
Content Writer

Every Amazon account has search terms that spend and never sell. On a mid-sized account it is usually a few hundred dollars a month, spread across dozens of terms, which is exactly why nobody gets round to it. The search-term report is long, the bulk file is longer, and negating by hand feels like busywork.
Here is the version that takes twenty minutes: one prompt, a short Python script, and a CSV of every term that spent money and sold nothing in the last thirty days, with the total at the bottom. Then an --apply flag that negates them, only when you say so.
Before you start
You need a SellerMate API key. Any workspace admin can create one from Profile → API Keys. For the audit, a read-only key is enough. If you want the script to negate terms too, you will need a read-and-write key, and it is sensible to limit that key to the account you are cleaning up.
1export SELLERMATE_API_KEY="sm_live_..."
The prompt
Paste this into Claude, ChatGPT or Cursor. The first line points it at the documentation so it reads the real parameters instead of inventing them.
1Read https://www.sellermate.ai/api-docs first. It documents the SellerMate Public API: REST over HTTPS, X-API-Key auth, and every tool with its parameters is on that page.23Build me a script that finds wasted search-term spend for one Amazon account.45It should:6- Pull the last 30 days of search terms with get_search_term_performance, walking every page7- Keep terms with at least 10 clicks and zero orders, or ACoS above 80%8- Write them to wasted-terms.csv with campaign, ad group, search term, clicks, spend, orders, ACoS9- Print the total spend on that list10- With an --apply flag, add the zero-order terms as negative exact keywords in their ad group using add_negative_keywords, 50 per call, and print what was added. Without the flag, change nothing.1112Let me pick the account from get_user_context, or take it as --account.1314Rules:15- My key is in the SELLERMATE_API_KEY environment variable. Send it as the X-API-Key header. Never hard-code it.16- Report tools are paginated (page, page_size up to 500, pagination.hasMore). Walk every page.17- On a 429, wait for the Retry-After header and retry.18- Show me the code before running anything that writes.1920Stack: Python 3 with requests. Keep it to one file.
It is also on the prompt library page with a copy button.
What you get back
The script the assistant writes will be forty to sixty lines. The shape is always the same, and it is worth understanding the three calls.
One helper for every tool. Every SellerMate tool is a POST to the same path with a JSON body, so one function covers the whole API:
1import os, requests23BASE = "https://api.sellermate.ai/public/v1/tools"4HEADERS = {"X-API-Key": os.environ["SELLERMATE_API_KEY"], "Content-Type": "application/json"}56def call(tool, **args):7 r = requests.post(f"{BASE}/{tool}", headers=HEADERS, json=args, timeout=120)8 r.raise_for_status()9 return r.json()
Pull every page of search terms. The tool returns rows plus a pagination block. A loop that stops when hasMore is false gets everything.
1rows, page = [], 02while True:3 res = call("get_search_term_performance", amazon_account_id=account_id,4 start_date=start, end_date=end, page=page, page_size=500)5 rows += res["data"]6 if not res["pagination"]["hasMore"]:7 break8 page += 1
Filter and total. Spend is cost, orders is purchases, ACoS is already computed.
1wasted = [r for r in rows if (r["clicks"] >= 10 and r["purchases"] == 0) or r["acos"] > 80]2print(f"{len(wasted)} terms, ${sum(r['cost'] for r in wasted):,.2f} wasted")
On a typical mid-sized account, that number is the one that gets the audit prioritised.
Negating, carefully
The --apply branch sends the zero-order terms to add_negative_keywords as exact-match negatives in the ad group they appeared in, fifty per call. Two things make this safer than a bulk file:
- Your guardrails run on every write. If a workspace policy blocks a change, the API returns 422 with the rule that blocked it, and nothing reaches Amazon. The script should print those and move on.
- Nothing changes without the flag. Run it three times without
--apply, read the CSV, lower the click threshold if the list looks thin, and only then apply.
1python wasted_spend.py --account <id> # audit only, writes wasted-terms.csv2python wasted_spend.py --account <id> --apply # negates the zero-order terms
Mistakes to avoid
- Negating high-ACoS terms as well as zero-order ones. A term at 90% ACoS with orders may be a keyword you are deliberately defending. The prompt only applies the zero-order group for a reason. Review the rest by hand.
- Using phrase match on exact-match campaigns. The script negates exact. If you run broad campaigns, tell the assistant to use phrase for those, and it will branch on the campaign's match type.
- Running it on the wrong account.
get_user_contextlists accounts with names and marketplaces. Pass--accountexplicitly in cron jobs rather than picking the first one.
Make it weekly
Once you trust the list, schedule it and post the CSV where the team will see it. The weekly client report guide shows the Slack side; the assistant can merge the two in a sentence.
A step further is to let SellerMate do the negating on an ongoing basis. Search-term harvesting and negation are built-in automation rules that run on every plan. The script is for the one-off clean-up and for the accounts where you want to see the list before anything changes.