@comchatx/cx-amazon-ads 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ComChatX
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,21 @@
1
- # Temporary Holding Version
1
+ # Amazon Ads
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ This plugin connects cx to your own Amazon advertising through Amazon's Ads API. Once you connect a store, cx can read your campaigns, ad groups, keywords, budgets and reports, and update your ads in the marketplaces you authorised, such as raising a budget or pausing a keyword.
4
+
5
+ Some things you can ask:
6
+
7
+ - What did my ads spend and sell in the last 7 days, campaign by campaign?
8
+ - Which campaigns run out of budget?
9
+ - Which keywords spend money without selling?
10
+
11
+ ## Connecting your store
12
+
13
+ Open the plugin's Settings and connect a store for each region you advertise in: North America, Europe or the Far East. Settings asks for your Ads API application's details and a refresh token, and Amazon's guide to authorization grants shows how to get them. Your keys stay with ComChatX and are never given to cx.
14
+
15
+ ## What it costs
16
+
17
+ Nothing. Neither Amazon nor ComChatX charges for Ads API calls. What your ads spend is between you and Amazon.
18
+
19
+ ## What it needs
20
+
21
+ It installs with cx-sources, through which cx reaches every data source.
@@ -0,0 +1,19 @@
1
+ 这个插件通过亚马逊的 Ads API 把 cx 连接到你自己的亚马逊广告。连接店铺后,cx 可以读取你的广告活动、广告组、关键词、预算和报告,也能在你授权的站点更新广告,比如提高预算、暂停关键词。
2
+
3
+ 你可以这样问:
4
+
5
+ - 最近 7 天,我的每个广告活动花了多少、卖了多少?
6
+ - 哪些广告活动的预算不够用?
7
+ - 哪些关键词只花钱不出单?
8
+
9
+ ## 连接店铺
10
+
11
+ 打开插件的「设置」,为你投放广告的每个区域连接一个店铺:北美、欧洲或远东。「设置」里要填写你的 Ads API 应用信息和刷新令牌,获取方法见亚马逊的授权指南。你的密钥保存在 ComChatX,不会交给 cx。
12
+
13
+ ## 费用
14
+
15
+ 免费。亚马逊和 ComChatX 都不对 Ads API 调用收费。广告本身的花费由你和亚马逊结算。
16
+
17
+ ## 依赖
18
+
19
+ 它会和 cx-sources 一起安装,cx 通过 cx-sources 使用所有数据源。
package/package.json CHANGED
@@ -1,6 +1,75 @@
1
1
  {
2
2
  "name": "@comchatx/cx-amazon-ads",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Reads and updates your own Amazon ads.",
5
+ "license": "MIT",
6
+ "author": "ComChatX",
7
+ "homepage": "https://github.com/comchatx/cx-amazon-ads#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/comchatx/cx-amazon-ads.git"
11
+ },
12
+ "bugs": "https://github.com/comchatx/cx-amazon-ads/issues",
13
+ "keywords": [
14
+ "pi-package"
15
+ ],
16
+ "type": "module",
17
+ "pi": {
18
+ "skills": [
19
+ "./skills"
20
+ ],
21
+ "prompts": [
22
+ "./prompts"
23
+ ]
24
+ },
25
+ "files": [
26
+ "skills",
27
+ "prompts",
28
+ "README.zh-CN.md"
29
+ ],
30
+ "scripts": {
31
+ "typecheck": "tsc --noEmit",
32
+ "test": "vitest run"
33
+ },
34
+ "comchatx": {
35
+ "name": "Amazon Ads",
36
+ "description": {
37
+ "zh": "读取并更新你自己的亚马逊广告。"
38
+ },
39
+ "mark": {
40
+ "line": "layout"
41
+ },
42
+ "section": "data",
43
+ "order": 21,
44
+ "skills": {
45
+ "amazon-ads": {
46
+ "zh": "通过亚马逊的 Ads API 读取并更新你在每个授权区域的亚马逊广告,包括广告活动、广告组、关键词、预算、竞价和报告。"
47
+ }
48
+ },
49
+ "prompts": {
50
+ "spend-this-week": {
51
+ "zh": "按广告活动查看最近 7 天的花费和销售额"
52
+ },
53
+ "out-of-budget": {
54
+ "zh": "找出预算不够用的广告活动"
55
+ },
56
+ "wasted-keywords": {
57
+ "zh": "找出只花钱不出单的关键词"
58
+ }
59
+ },
60
+ "source": {
61
+ "name": "amazon-ads",
62
+ "help": "https://advertising.amazon.com/API/docs/en-us/guides/account-management/authorization/authorization-grants",
63
+ "aspects": {}
64
+ }
65
+ },
66
+ "dependencies": {
67
+ "cx-sources": "^0.1.3"
68
+ },
69
+ "devDependencies": {
70
+ "@earendil-works/pi-coding-agent": "1.4.0",
71
+ "@types/node": "26.2.0",
72
+ "typescript": "7.0.2",
73
+ "vitest": "4.1.11"
74
+ }
75
+ }
@@ -0,0 +1,4 @@
1
+ ---
2
+ description: Find campaigns that run out of budget
3
+ ---
4
+ Find my enabled Amazon Ads campaigns that ran out of their daily budget in the last seven days. For each, show the budget, what it spent and its sales, and suggest a new budget. Change nothing until I say so.
@@ -0,0 +1,4 @@
1
+ ---
2
+ description: See ad spend and sales for the last 7 days, by campaign
3
+ ---
4
+ Show my Amazon Ads spend, sales and ACOS for the last seven days, campaign by campaign, in each marketplace I advertise in, in each marketplace's currency. Put the campaigns that spent the most first.
@@ -0,0 +1,4 @@
1
+ ---
2
+ description: Find keywords that spend without selling
3
+ ---
4
+ Find the keywords and search terms in my Sponsored Products campaigns that spent money in the last thirty days with no sales. Show what each spent, and suggest which to pause or add as negative keywords. Change nothing until I say so.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: amazon-ads
3
+ description: The seller's own Amazon Ads accounts through Amazon's Ads API — profiles, Sponsored Products, Sponsored Brands and Sponsored Display campaigns, ad groups, ads, keywords and targets, budgets, bids and reports, read and changed, in each region the seller authorised. Use before the first call that reads or changes the seller's own Amazon advertising. Needs cx-sources; if no cx-sources skill is listed, it is not installed, and the seller installs it in Plugins.
4
+ ---
5
+
6
+ Amazon Ads is an open door through `cx raw`; read cx-sources first. The door carries any method, path, query, header and body to the origin the request names, attaches the seller's token and client id, and lands Amazon's reply as Amazon gave it, at no charge. If Amazon Ads is off, the seller turns its plugin on in Plugins.
7
+
8
+ ```sh
9
+ cx raw amazon-ads --origin https://advertising-api.amazon.com --method GET --path /v2/profiles
10
+ ```
11
+
12
+ Amazon's reference: <https://advertising.amazon.com/API/docs/en-us>.
13
+
14
+ ## Origins and connections
15
+
16
+ | Origin | Region | Marketplaces |
17
+ |---|---|---|
18
+ | `https://advertising-api.amazon.com` | `na` | US, CA, MX, BR |
19
+ | `https://advertising-api-eu.amazon.com` | `eu` | UK, FR, IT, ES, DE, NL, AE, PL, TR, EG, SA, SE, BE, IN, ZA |
20
+ | `https://advertising-api-fe.amazon.com` | `fe` | JP, AU, SG |
21
+
22
+ The platform holds the client pair, `client_id` and `client_secret`, and the seller's connections, each a store, its region and its `refresh_token`; the box holds none. A call goes on its origin region's connection; where the region holds several, `--header x-cx-store=<store>` names one, and Amazon never sees it. Without the client pair or that connection, the door refuses `key_required`, naming what is missing, before anything is sent. A request naming `Authorization`, `Amazon-Advertising-API-ClientId` or `Amazon-Ads-ClientId` is refused.
23
+
24
+ ## Profiles
25
+
26
+ Nearly every call names one advertising account in one marketplace: `--header Amazon-Advertising-API-Scope=<profileId>`. Read the ids from `GET /v2/profiles` at the region's origin; each profile's `countryCode` names its marketplace. An empty list means the grant works but reaches no account there with View and Edit permission.
27
+
28
+ ## The door
29
+
30
+ - A `429` is Amazon's answer: the door adds no wait.
31
+ - Many lists are a `POST`; the gate reads a `POST` as a change, so one whose reply was lost reads `sent, outcome unknown`.
32
+ - A `GET` or `HEAD` with a body, `TRACE`, `CONNECT` and `TRACK` are not sent.
33
+ - A report's `url` is the box's own download, outside the door.
34
+
35
+ Paths, media types, reports, budgets and failures: [references/door.md](references/door.md).
@@ -0,0 +1,53 @@
1
+ # The Amazon Ads door
2
+
3
+ This file holds two kinds of line. Amazon's facts are from its Ads API guides at <https://advertising.amazon.com/API/docs/en-us>, read 2026-11-03, with the page named beside each. The door's own behaviour — the token step, the refusals, the endings, and the gate's reading of a `POST` — is ComChatX's, and names no page.
4
+
5
+ ## The token step
6
+
7
+ Every call begins with one trade at Login with Amazon, `https://api.amazon.com/auth/o2/token`, of the connection's refresh token for an access token; the door remembers no token between calls. The request then goes with `Authorization: Bearer <access token>` and `Amazon-Advertising-API-ClientId: <client id>`, the header Amazon's own examples use on `/v2/profiles` and on `/adsApi/v1/create/campaigns` (*Retrieve a profile ID*; *Sponsored Products campaigns*). Other guides name it `Amazon-Ads-ClientId`; the door attaches its own, and a request naming either is refused `out_of_scope`.
8
+
9
+ A trade Amazon refuses ends the call `failed` with nothing of the request sent, Amazon's words under the line: `refresh-token trade, HTTP 400: invalid_grant: …` means the refresh token is not valid — revoked, expired, or issued to another application — and the seller saves a new one on the plugin's Settings; `invalid_client` means the client pair. Refresh tokens issued on or after 2026-07-30 expire 365 days after the advertiser's consent (*Refresh tokens*).
10
+
11
+ The door expects one refresh token, one Amazon user's grant, to serve every region; this is the door's expectation, not a line of Amazon's guides. The seller saves a connection with it in each region they advertise in.
12
+
13
+ ## Headers a request names
14
+
15
+ | Header | When (*Making your first call*, *Get started with Amazon Ads API v1*) |
16
+ |---|---|
17
+ | `Amazon-Advertising-API-Scope` | The profile id, for campaign management and most sponsored ads requests. Every call but `/v2/profiles` reaches one profile. |
18
+ | `Amazon-Ads-AccountId` | The advertising account id, for reporting across ad products and for cross-product calls. |
19
+ | `Accept`, `Content-Type` | The versioned media type an operation names, as `application/vnd.spCampaign.v3+json`; without `Accept` Amazon answers `application/json`. |
20
+
21
+ The door composes no `content-type`: a body goes with the headers the request names. It sends its own `user-agent` when the request names none.
22
+
23
+ ## Profiles
24
+
25
+ `GET /v2/profiles` lists the advertising accounts the grant reaches in the origin's region, one profile a marketplace: `profileId`, `countryCode`, `currencyCode`, `timezone` and `accountInfo` (`marketplaceStringId`, `id`, `type`, `name`). An empty list means no account there with View and Edit permission; the `accessLevel` query of the Profiles specification lists view-only ones too (*Retrieve a profile ID*). It does not list Amazon DSP advertiser accounts.
26
+
27
+ ## Campaigns, ad groups, ads and targets
28
+
29
+ - Lists, a `POST` with a filter body: Sponsored Products `POST /sp/campaigns/list` under `application/vnd.spCampaign.v3+json`, Sponsored Brands `POST /sb/v4/campaigns/list` under `application/vnd.sbcampaignresource.v4+json` (*Making your first call*).
30
+ - Ads API v1 creates across ad products: `POST /adsApi/v1/create/campaigns`, `/adsApi/v1/create/adGroups`, `/adsApi/v1/create/ads` and `/adsApi/v1/create/targets`, a keyword being a target; a create answers `207` with `success` and `error`, each entry naming its `index` in the request (*Sponsored Products campaigns*, *Sponsored Products ad groups*, *Get started with manual campaigns*).
31
+ - Recommendations: `POST /sp/targets/keywords/recommendations`, `POST /sp/targets/products/recommendations`, `POST /sp/targets/bid/recommendations`, `GET /sp/targets/categories`.
32
+ - A path is one Amazon's reference lists, never a guess; an id in a path or a body is one read from a reply or named by the seller.
33
+
34
+ ## Budgets
35
+
36
+ A campaign's budget in Ads API v1 is a list: `budgets: [{ budgetType: "MONETARY", budgetValue: { monetaryBudgetValue: { monetaryBudget: { value } } }, recurrenceTimePeriod: "DAILY" }]`, in the profile's currency (*Sponsored Products campaigns*). A budget is changed by the campaign's update operation in Amazon's reference, sent as written; there is no write switch, and a change is sent as a read is.
37
+
38
+ ## Reports
39
+
40
+ Reporting v3 is asynchronous, in three calls (*Get started with version 3 reports*):
41
+
42
+ 1. `POST /reporting/reports` under `Content-Type: application/vnd.createasyncreportrequest.v3+json`, with `name`, `startDate`, `endDate` and a `configuration` of `adProduct` (`SPONSORED_PRODUCTS`, …), `groupBy`, `columns`, `reportTypeId` (`spCampaigns`, …), `timeUnit` (`DAILY`, with `date` among the columns, or `SUMMARY`, with `startDate` and `endDate`) and `format` `GZIP_JSON`. It answers `200` with a `reportId`. A request identical to one still generating answers `425`, too soon.
43
+ 2. `GET /reporting/reports/{reportId}` until `status` is `COMPLETED`; `PENDING` and `PROCESSING` mean not yet. Generation takes up to three hours, and repeated status calls may be answered `429`; Amazon's page asks for a delay between them.
44
+ 3. The `url` of the completed report is an S3 address: the box's own download, outside the door, gzipped JSON rows.
45
+
46
+ Amazon deprecates reporting v3 on 2027-06-30 for its new reporting API.
47
+
48
+ ## The reply
49
+
50
+ - A reply outside 2xx that the door returns lands with its status, its headers and as much of its body as came, and the call ends `failed`, exit 1: the line reads `the source answered HTTP 403`, with the status and the reply's opening under it; a returned `429` is `provider_rate_limit`. A redirect is followed nowhere and nothing of it lands: a read ends `failed`, a change reads `sent, outcome unknown`.
51
+ - A reply cut short ends `failed`, exit 1, whatever its status, with the bytes that came landed.
52
+ - A `429` is Amazon's answer; its `Retry-After` header, where present, gives the seconds to wait (*Rate limiting*). The door adds no wait and retries nothing. Amazon's *Rate limiting* page recommends exponential backoff where `429`s recur, and longer backoff for report generation.
53
+ - A list sent as a `POST` is a change to the gate: lost after it left, it reads `sent, outcome unknown`, though a list changes nothing at Amazon.