@biggora/claude-plugins 1.2.0 → 1.2.2
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/README.md +11 -4
- package/package.json +1 -1
- package/registry/registry.json +319 -244
- package/specs/coding.md +24 -0
- package/specs/pod.md +2 -0
- package/src/skills/captcha/README.md +221 -0
- package/src/skills/captcha/SKILL.md +355 -0
- package/src/skills/captcha/references/captcha-types.md +254 -0
- package/src/skills/captcha/references/services.md +172 -0
- package/src/skills/captcha/references/stealth.md +238 -0
- package/src/skills/captcha/scripts/solve_captcha.py +323 -0
- package/src/skills/captcha/scripts/solve_image_grid.py +350 -0
- package/src/skills/google-merchant-api/SKILL.md +581 -0
- package/src/skills/google-merchant-api/references/accounts.md +247 -0
- package/src/skills/google-merchant-api/references/content-api-legacy.md +216 -0
- package/src/skills/google-merchant-api/references/datasources.md +233 -0
- package/src/skills/google-merchant-api/references/inventories.md +201 -0
- package/src/skills/google-merchant-api/references/migration.md +267 -0
- package/src/skills/google-merchant-api/references/products.md +316 -0
- package/src/skills/google-merchant-api/references/promotions.md +201 -0
- package/src/skills/google-merchant-api/references/reports.md +240 -0
- package/src/skills/lv-aggregators-api/SKILL.md +113 -0
- package/src/skills/lv-aggregators-api/references/integration-guide.md +368 -0
- package/src/skills/lv-aggregators-api/references/kurpirkt.md +103 -0
- package/src/skills/lv-aggregators-api/references/salidzini.md +122 -0
- package/src/skills/tailwindcss-best-practices/SKILL.md +180 -0
- package/src/skills/tailwindcss-best-practices/references/best-practices-utility-patterns.md +87 -0
- package/src/skills/tailwindcss-best-practices/references/core-installation.md +109 -0
- package/src/skills/tailwindcss-best-practices/references/core-preflight.md +200 -0
- package/src/skills/tailwindcss-best-practices/references/core-responsive.md +163 -0
- package/src/skills/tailwindcss-best-practices/references/core-source-detection.md +114 -0
- package/src/skills/tailwindcss-best-practices/references/core-theme.md +108 -0
- package/src/skills/tailwindcss-best-practices/references/core-utility-classes.md +59 -0
- package/src/skills/tailwindcss-best-practices/references/core-variants.md +204 -0
- package/src/skills/tailwindcss-best-practices/references/effects-form-controls.md +76 -0
- package/src/skills/tailwindcss-best-practices/references/effects-mask.md +91 -0
- package/src/skills/tailwindcss-best-practices/references/effects-scroll-snap.md +59 -0
- package/src/skills/tailwindcss-best-practices/references/effects-text-shadow.md +78 -0
- package/src/skills/tailwindcss-best-practices/references/effects-transition-animation.md +80 -0
- package/src/skills/tailwindcss-best-practices/references/effects-visibility-interactivity.md +82 -0
- package/src/skills/tailwindcss-best-practices/references/features-content-detection.md +175 -0
- package/src/skills/tailwindcss-best-practices/references/features-custom-styles.md +203 -0
- package/src/skills/tailwindcss-best-practices/references/features-dark-mode.md +137 -0
- package/src/skills/tailwindcss-best-practices/references/features-functions-directives.md +241 -0
- package/src/skills/tailwindcss-best-practices/references/features-upgrade.md +160 -0
- package/src/skills/tailwindcss-best-practices/references/layout-aspect-ratio.md +39 -0
- package/src/skills/tailwindcss-best-practices/references/layout-columns.md +80 -0
- package/src/skills/tailwindcss-best-practices/references/layout-display.md +110 -0
- package/src/skills/tailwindcss-best-practices/references/layout-flexbox.md +112 -0
- package/src/skills/tailwindcss-best-practices/references/layout-grid.md +87 -0
- package/src/skills/tailwindcss-best-practices/references/layout-height.md +97 -0
- package/src/skills/tailwindcss-best-practices/references/layout-inset.md +103 -0
- package/src/skills/tailwindcss-best-practices/references/layout-logical-properties.md +92 -0
- package/src/skills/tailwindcss-best-practices/references/layout-margin.md +126 -0
- package/src/skills/tailwindcss-best-practices/references/layout-min-max-sizing.md +63 -0
- package/src/skills/tailwindcss-best-practices/references/layout-object-fit-position.md +64 -0
- package/src/skills/tailwindcss-best-practices/references/layout-overflow.md +57 -0
- package/src/skills/tailwindcss-best-practices/references/layout-padding.md +77 -0
- package/src/skills/tailwindcss-best-practices/references/layout-position.md +85 -0
- package/src/skills/tailwindcss-best-practices/references/layout-tables.md +67 -0
- package/src/skills/tailwindcss-best-practices/references/layout-width.md +102 -0
- package/src/skills/tailwindcss-best-practices/references/transform-base.md +68 -0
- package/src/skills/tailwindcss-best-practices/references/transform-rotate.md +70 -0
- package/src/skills/tailwindcss-best-practices/references/transform-scale.md +83 -0
- package/src/skills/tailwindcss-best-practices/references/transform-skew.md +62 -0
- package/src/skills/tailwindcss-best-practices/references/transform-translate.md +77 -0
- package/src/skills/tailwindcss-best-practices/references/typography-font-text.md +142 -0
- package/src/skills/tailwindcss-best-practices/references/typography-list-style.md +65 -0
- package/src/skills/tailwindcss-best-practices/references/typography-text-align.md +60 -0
- package/src/skills/tailwindcss-best-practices/references/visual-background.md +76 -0
- package/src/skills/tailwindcss-best-practices/references/visual-border.md +108 -0
- package/src/skills/tailwindcss-best-practices/references/visual-effects.md +111 -0
- package/src/skills/tailwindcss-best-practices/references/visual-svg.md +82 -0
- package/src/skills/test-mobile-app/SKILL.md +11 -6
- package/src/skills/test-mobile-app/scripts/analyze_apk.py +15 -4
- package/src/skills/test-mobile-app/scripts/check_environment.py +5 -5
- package/src/skills/test-mobile-app/scripts/run_tests.py +1 -1
- package/src/skills/test-web-ui/SKILL.md +264 -84
- package/src/skills/test-web-ui/scripts/discover.py +25 -12
- package/src/skills/test-web-ui/scripts/run_tests.py +3 -2
- package/src/skills/vite-best-practices/SKILL.md +115 -0
- package/src/skills/vite-best-practices/references/build-and-ssr.md +255 -0
- package/src/skills/vite-best-practices/references/core-config.md +231 -0
- package/src/skills/vite-best-practices/references/core-features.md +222 -0
- package/src/skills/vite-best-practices/references/core-plugin-api.md +294 -0
- package/src/skills/vite-best-practices/references/environment-api.md +108 -0
- package/src/skills/vite-best-practices/references/rolldown-migration.md +242 -0
- package/codex-cli-workspace/iteration-1/benchmark.json +0 -122
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/eval_metadata.json +0 -13
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/grading.json +0 -52
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/outputs/response.md +0 -163
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/grading.json +0 -58
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/outputs/response.md +0 -151
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/eval_metadata.json +0 -13
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/grading.json +0 -52
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -86
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/grading.json +0 -58
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -164
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/eval_metadata.json +0 -13
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/grading.json +0 -52
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/outputs/response.md +0 -130
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/grading.json +0 -64
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/outputs/response.md +0 -209
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/review.html +0 -1325
- package/gemini-cli-workspace/iteration-1/benchmark.json +0 -86
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/eval_metadata.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/outputs/response.md +0 -401
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/outputs/response.md +0 -405
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/eval_metadata.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -212
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -427
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/eval_metadata.json +0 -32
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/grading.json +0 -32
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/outputs/response.md +0 -171
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/grading.json +0 -32
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/outputs/response.md +0 -199
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/review.html +0 -1325
- package/gemini-cli-workspace/iteration-2/benchmark.json +0 -173
- package/gemini-cli-workspace/iteration-2/benchmark.md +0 -28
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/eval_metadata.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/outputs/response.md +0 -195
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/outputs/response.md +0 -377
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/eval_metadata.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -127
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -164
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/eval_metadata.json +0 -32
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/grading.json +0 -32
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/outputs/response.md +0 -91
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/grading.json +0 -32
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/outputs/response.md +0 -112
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-viewer.html +0 -1325
- package/screen-recording-workspace/evals.json +0 -41
- package/screen-recording-workspace/iteration-1/benchmark.json +0 -102
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/eval_metadata.json +0 -31
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/outputs/demo.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/outputs/demo.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/eval_metadata.json +0 -31
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/outputs/region_capture.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/outputs/region_capture.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/eval_metadata.json +0 -31
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/outputs/fallback_recording.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/outputs/fallback_recording.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/outputs/record_screen.py +0 -67
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/review.html +0 -1325
- package/src/skills/codex-cli/evals/evals.json +0 -47
- package/src/skills/gemini-cli/evals/evals.json +0 -46
- package/src/skills/tm-search/evals/evals.json +0 -23
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Inventories Sub-API Reference
|
|
2
|
+
|
|
3
|
+
Base: `https://merchantapi.googleapis.com/inventories/v1`
|
|
4
|
+
|
|
5
|
+
Manage product availability and pricing at the store level (local) or region level (regional).
|
|
6
|
+
|
|
7
|
+
## Local Inventories
|
|
8
|
+
|
|
9
|
+
Store-level inventory for brick-and-mortar locations.
|
|
10
|
+
|
|
11
|
+
| Method | Endpoint | Description |
|
|
12
|
+
|--------|----------|-------------|
|
|
13
|
+
| `POST` | `/accounts/{account}/products/{product}/localInventories` | Insert/update local inventory |
|
|
14
|
+
| `GET` | `/accounts/{account}/products/{product}/localInventories` | List local inventories |
|
|
15
|
+
| `DELETE` | `/accounts/{account}/products/{product}/localInventories/{storeCode}` | Delete local inventory |
|
|
16
|
+
|
|
17
|
+
### LocalInventory Object
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"name": "accounts/123456/products/en~US~SKU001/localInventories/STORE-NYC-01",
|
|
22
|
+
"account": "accounts/123456",
|
|
23
|
+
"storeCode": "STORE-NYC-01",
|
|
24
|
+
"availability": "in_stock",
|
|
25
|
+
"price": {
|
|
26
|
+
"amountMicros": "69990000",
|
|
27
|
+
"currencyCode": "USD"
|
|
28
|
+
},
|
|
29
|
+
"salePrice": {
|
|
30
|
+
"amountMicros": "59990000",
|
|
31
|
+
"currencyCode": "USD"
|
|
32
|
+
},
|
|
33
|
+
"salePriceEffectiveDate": {
|
|
34
|
+
"startTime": "2024-12-01T00:00:00Z",
|
|
35
|
+
"endTime": "2024-12-31T23:59:59Z"
|
|
36
|
+
},
|
|
37
|
+
"quantity": "25",
|
|
38
|
+
"pickupMethod": "buy",
|
|
39
|
+
"pickupSla": "same day",
|
|
40
|
+
"instoreProductLocation": "Aisle 5, Shelf B",
|
|
41
|
+
"customAttributes": [
|
|
42
|
+
{ "name": "display_unit", "value": "true" }
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Fields
|
|
48
|
+
|
|
49
|
+
| Field | Type | Required | Description |
|
|
50
|
+
|-------|------|----------|-------------|
|
|
51
|
+
| `storeCode` | string | Required | Your store identifier (must match Google Business Profile) |
|
|
52
|
+
| `availability` | enum | Optional | `in_stock`, `out_of_stock`, `preorder`, `backorder` |
|
|
53
|
+
| `price` | Price | Optional | Store-specific price override |
|
|
54
|
+
| `salePrice` | Price | Optional | Store-specific sale price |
|
|
55
|
+
| `salePriceEffectiveDate` | Interval | Optional | Sale period |
|
|
56
|
+
| `quantity` | int64 | Optional | Stock quantity |
|
|
57
|
+
| `pickupMethod` | enum | Optional | `buy`, `reserve`, `ship_to_store`, `not_supported` |
|
|
58
|
+
| `pickupSla` | enum | Optional | `same_day`, `next_day`, `2_day` ... `7_day`, `multi_week` |
|
|
59
|
+
| `instoreProductLocation` | string | Optional | Physical location in store |
|
|
60
|
+
| `customAttributes[]` | array | Optional | Additional attributes |
|
|
61
|
+
|
|
62
|
+
### Insert Example
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
const MERCHANT_ID = '123456';
|
|
66
|
+
const PRODUCT_ID = 'en~US~SKU001';
|
|
67
|
+
|
|
68
|
+
const localInventory = {
|
|
69
|
+
storeCode: 'STORE-NYC-01',
|
|
70
|
+
availability: 'in_stock',
|
|
71
|
+
price: { amountMicros: '69990000', currencyCode: 'USD' },
|
|
72
|
+
quantity: '25',
|
|
73
|
+
pickupMethod: 'buy',
|
|
74
|
+
pickupSla: 'same_day',
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const response = await fetch(
|
|
78
|
+
`https://merchantapi.googleapis.com/inventories/v1/accounts/${MERCHANT_ID}/products/${PRODUCT_ID}/localInventories`,
|
|
79
|
+
{
|
|
80
|
+
method: 'POST',
|
|
81
|
+
headers: {
|
|
82
|
+
'Authorization': `Bearer ${token}`,
|
|
83
|
+
'Content-Type': 'application/json',
|
|
84
|
+
},
|
|
85
|
+
body: JSON.stringify(localInventory),
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Regional Inventories
|
|
91
|
+
|
|
92
|
+
Region-level overrides for pricing and availability based on geographic regions you define.
|
|
93
|
+
|
|
94
|
+
| Method | Endpoint | Description |
|
|
95
|
+
|--------|----------|-------------|
|
|
96
|
+
| `POST` | `/accounts/{account}/products/{product}/regionalInventories` | Insert/update regional inventory |
|
|
97
|
+
| `GET` | `/accounts/{account}/products/{product}/regionalInventories` | List regional inventories |
|
|
98
|
+
| `DELETE` | `/accounts/{account}/products/{product}/regionalInventories/{region}` | Delete regional inventory |
|
|
99
|
+
|
|
100
|
+
### RegionalInventory Object
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"name": "accounts/123456/products/en~US~SKU001/regionalInventories/northeast",
|
|
105
|
+
"account": "accounts/123456",
|
|
106
|
+
"region": "northeast",
|
|
107
|
+
"availability": "in_stock",
|
|
108
|
+
"price": {
|
|
109
|
+
"amountMicros": "74990000",
|
|
110
|
+
"currencyCode": "USD"
|
|
111
|
+
},
|
|
112
|
+
"salePrice": {
|
|
113
|
+
"amountMicros": "64990000",
|
|
114
|
+
"currencyCode": "USD"
|
|
115
|
+
},
|
|
116
|
+
"salePriceEffectiveDate": {
|
|
117
|
+
"startTime": "2024-12-01T00:00:00Z",
|
|
118
|
+
"endTime": "2024-12-31T23:59:59Z"
|
|
119
|
+
},
|
|
120
|
+
"customAttributes": []
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Fields
|
|
125
|
+
|
|
126
|
+
| Field | Type | Required | Description |
|
|
127
|
+
|-------|------|----------|-------------|
|
|
128
|
+
| `region` | string | Required | Region ID (must be defined via Accounts > Regions) |
|
|
129
|
+
| `availability` | enum | Optional | Same as local inventory |
|
|
130
|
+
| `price` | Price | Optional | Region-specific price override |
|
|
131
|
+
| `salePrice` | Price | Optional | Region-specific sale price |
|
|
132
|
+
| `salePriceEffectiveDate` | Interval | Optional | Sale period |
|
|
133
|
+
| `customAttributes[]` | array | Optional | Additional attributes |
|
|
134
|
+
|
|
135
|
+
### Workflow: Set Up Regional Pricing
|
|
136
|
+
|
|
137
|
+
1. **Define regions** via the Accounts sub-API:
|
|
138
|
+
```javascript
|
|
139
|
+
// Create a region
|
|
140
|
+
await fetch(
|
|
141
|
+
`https://merchantapi.googleapis.com/accounts/v1/accounts/${MERCHANT_ID}/regions`,
|
|
142
|
+
{
|
|
143
|
+
method: 'POST',
|
|
144
|
+
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
145
|
+
body: JSON.stringify({
|
|
146
|
+
displayName: 'US Northeast',
|
|
147
|
+
postalCodeArea: {
|
|
148
|
+
regionCode: 'US',
|
|
149
|
+
postalCodes: [
|
|
150
|
+
{ begin: '10000', end: '14999' },
|
|
151
|
+
{ begin: '06000', end: '06999' },
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
}),
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
2. **Set regional inventory** for products:
|
|
160
|
+
```javascript
|
|
161
|
+
await fetch(
|
|
162
|
+
`https://merchantapi.googleapis.com/inventories/v1/accounts/${MERCHANT_ID}/products/en~US~SKU001/regionalInventories`,
|
|
163
|
+
{
|
|
164
|
+
method: 'POST',
|
|
165
|
+
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
166
|
+
body: JSON.stringify({
|
|
167
|
+
region: 'northeast',
|
|
168
|
+
price: { amountMicros: '74990000', currencyCode: 'USD' },
|
|
169
|
+
availability: 'in_stock',
|
|
170
|
+
}),
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Bulk Inventory Updates
|
|
176
|
+
|
|
177
|
+
For updating many products' inventory, use async parallel requests:
|
|
178
|
+
|
|
179
|
+
```javascript
|
|
180
|
+
// Update inventory for multiple products in parallel
|
|
181
|
+
const inventoryUpdates = [
|
|
182
|
+
{ productId: 'en~US~SKU001', storeCode: 'STORE-01', quantity: '50', availability: 'in_stock' },
|
|
183
|
+
{ productId: 'en~US~SKU002', storeCode: 'STORE-01', quantity: '0', availability: 'out_of_stock' },
|
|
184
|
+
{ productId: 'en~US~SKU003', storeCode: 'STORE-01', quantity: '12', availability: 'in_stock' },
|
|
185
|
+
];
|
|
186
|
+
|
|
187
|
+
const results = await Promise.allSettled(
|
|
188
|
+
inventoryUpdates.map(({ productId, ...inventory }) =>
|
|
189
|
+
fetch(
|
|
190
|
+
`https://merchantapi.googleapis.com/inventories/v1/accounts/${MERCHANT_ID}/products/${productId}/localInventories`,
|
|
191
|
+
{
|
|
192
|
+
method: 'POST',
|
|
193
|
+
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
194
|
+
body: JSON.stringify(inventory),
|
|
195
|
+
}
|
|
196
|
+
)
|
|
197
|
+
)
|
|
198
|
+
);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Respect rate limits — implement exponential backoff for `429` responses.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Migration: Content API for Shopping to Merchant API
|
|
2
|
+
|
|
3
|
+
The Content API for Shopping (v2.1) sunsets **August 18, 2026**. The Merchant API (v1) is the replacement.
|
|
4
|
+
|
|
5
|
+
## Key Architectural Changes
|
|
6
|
+
|
|
7
|
+
### 1. Products Split into Input + Output
|
|
8
|
+
|
|
9
|
+
**Content API:** Single `products` resource for read and write.
|
|
10
|
+
|
|
11
|
+
**Merchant API:** Split into:
|
|
12
|
+
- `productInputs` - What you submit (write)
|
|
13
|
+
- `products` - What Google processed (read-only, includes status)
|
|
14
|
+
|
|
15
|
+
This means `productstatuses` is gone — status is now part of the `products` resource.
|
|
16
|
+
|
|
17
|
+
### 2. Modular Sub-APIs
|
|
18
|
+
|
|
19
|
+
**Content API:** Monolithic API with all resources under one service.
|
|
20
|
+
|
|
21
|
+
**Merchant API:** 14 independent sub-APIs, each with own versioning:
|
|
22
|
+
- `products/v1`, `accounts/v1`, `inventories/v1`, `reports/v1`, etc.
|
|
23
|
+
|
|
24
|
+
### 3. Resource Naming
|
|
25
|
+
|
|
26
|
+
**Content API ID format:**
|
|
27
|
+
```
|
|
28
|
+
channel:contentLanguage:targetCountry:offerId
|
|
29
|
+
Example: online:en:US:sku123
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Merchant API name format:**
|
|
33
|
+
```
|
|
34
|
+
accounts/{accountId}/products/{contentLanguage}~{feedLabel}~{offerId}
|
|
35
|
+
Example: accounts/123456/products/en~US~sku123
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 4. Price Format
|
|
39
|
+
|
|
40
|
+
**Content API:**
|
|
41
|
+
```json
|
|
42
|
+
{ "value": "79.99", "currency": "USD" }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Merchant API:**
|
|
46
|
+
```json
|
|
47
|
+
{ "amountMicros": "79990000", "currencyCode": "USD" }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Conversion: `amountMicros = value * 1000000`
|
|
51
|
+
|
|
52
|
+
### 5. Field Nesting
|
|
53
|
+
|
|
54
|
+
**Content API:** Flat top-level attributes.
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"offerId": "SKU-001",
|
|
58
|
+
"title": "My Product",
|
|
59
|
+
"price": { "value": "79.99", "currency": "USD" }
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Merchant API:** Attributes nested under `productAttributes`.
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"offerId": "SKU-001",
|
|
67
|
+
"productAttributes": {
|
|
68
|
+
"title": "My Product",
|
|
69
|
+
"price": { "amountMicros": "79990000", "currencyCode": "USD" }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 6. targetCountry → feedLabel
|
|
75
|
+
|
|
76
|
+
`targetCountry` is renamed to `feedLabel`. Values are the same (e.g., `US`, `GB`).
|
|
77
|
+
|
|
78
|
+
### 7. Batching
|
|
79
|
+
|
|
80
|
+
**Content API:** `customBatch` methods.
|
|
81
|
+
|
|
82
|
+
**Merchant API:** No custom batch. Use async parallel requests or HTTP batching instead.
|
|
83
|
+
|
|
84
|
+
### 8. Data Source Required
|
|
85
|
+
|
|
86
|
+
All `productInputs` write operations require a `dataSource` query parameter:
|
|
87
|
+
```
|
|
88
|
+
POST /products/v1/accounts/{id}/productInputs:insert?dataSource=accounts/{id}/dataSources/{dsId}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 9. Base64url Encoding
|
|
92
|
+
|
|
93
|
+
Product names containing special characters (`% . + / : ~ , ( * ! ) & ? = @ # $`) must use unpadded base64url encoding (RFC 4648 Section 5).
|
|
94
|
+
|
|
95
|
+
## Method Mapping
|
|
96
|
+
|
|
97
|
+
| Content API Method | Merchant API Method |
|
|
98
|
+
|-------------------|---------------------|
|
|
99
|
+
| `products.insert` | `productInputs:insert` |
|
|
100
|
+
| `products.update` | `productInputs:patch` |
|
|
101
|
+
| `products.delete` | `productInputs:delete` |
|
|
102
|
+
| `products.get` | `products.get` |
|
|
103
|
+
| `products.list` | `products.list` |
|
|
104
|
+
| `products.custombatch` | Async parallel requests |
|
|
105
|
+
| `productstatuses.get` | `products.get` (status included) |
|
|
106
|
+
| `productstatuses.list` | `products.list` (status included) |
|
|
107
|
+
| `productstatuses.custombatch` | Async parallel requests |
|
|
108
|
+
| `accounts.get` | `accounts.get` |
|
|
109
|
+
| `accounts.list` | `accounts.list` |
|
|
110
|
+
| `accounts.update` | `accounts.patch` |
|
|
111
|
+
| `accounts.insert` | `accounts:createAndConfigure` |
|
|
112
|
+
| `accounts.delete` | `accounts.delete` |
|
|
113
|
+
| `accountstatuses.get` | `accounts/{id}/issues.list` |
|
|
114
|
+
| `datafeeds.*` | `dataSources.*` |
|
|
115
|
+
| `datafeedstatuses.*` | `dataSources/{id}/fileUploads/{id}` |
|
|
116
|
+
| `liasettings.*` | `omnichannelSettings.*` |
|
|
117
|
+
| `shippingsettings.*` | `shippingSettings.*` |
|
|
118
|
+
| `regions.*` | `regions.*` |
|
|
119
|
+
| `returnpolicy.*` | `onlineReturnPolicies.*` |
|
|
120
|
+
|
|
121
|
+
## Migration Strategy
|
|
122
|
+
|
|
123
|
+
### Recommended Order
|
|
124
|
+
|
|
125
|
+
1. **Accounts** - Foundation for everything else
|
|
126
|
+
2. **Products** - Core product management
|
|
127
|
+
3. **Data Sources** - Feed management (compatible across APIs)
|
|
128
|
+
4. **Reports** - Performance data
|
|
129
|
+
5. **Everything else** - Promotions, inventory, notifications, etc.
|
|
130
|
+
|
|
131
|
+
### Incremental Approach
|
|
132
|
+
|
|
133
|
+
You can migrate one sub-API at a time. Content API and Merchant API can coexist:
|
|
134
|
+
- Data sources created with Content API work with Merchant API
|
|
135
|
+
- Products inserted via Content API are visible through Merchant API
|
|
136
|
+
- Migrate sub-APIs independently, test each before moving to the next
|
|
137
|
+
|
|
138
|
+
### Code Migration Example
|
|
139
|
+
|
|
140
|
+
**Before (Content API):**
|
|
141
|
+
```javascript
|
|
142
|
+
// Insert product
|
|
143
|
+
const response = await fetch(
|
|
144
|
+
`https://shoppingcontent.googleapis.com/content/v2.1/${MERCHANT_ID}/products`,
|
|
145
|
+
{
|
|
146
|
+
method: 'POST',
|
|
147
|
+
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
148
|
+
body: JSON.stringify({
|
|
149
|
+
offerId: 'SKU-001',
|
|
150
|
+
title: 'Premium Headphones',
|
|
151
|
+
description: 'Great headphones',
|
|
152
|
+
link: 'https://example.com/product',
|
|
153
|
+
imageLink: 'https://example.com/image.jpg',
|
|
154
|
+
contentLanguage: 'en',
|
|
155
|
+
targetCountry: 'US',
|
|
156
|
+
channel: 'online',
|
|
157
|
+
availability: 'in stock',
|
|
158
|
+
condition: 'new',
|
|
159
|
+
price: { value: '79.99', currency: 'USD' },
|
|
160
|
+
brand: 'AudioBrand',
|
|
161
|
+
gtin: '0123456789012',
|
|
162
|
+
}),
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// Get product status
|
|
167
|
+
const status = await fetch(
|
|
168
|
+
`https://shoppingcontent.googleapis.com/content/v2.1/${MERCHANT_ID}/productstatuses/online:en:US:SKU-001`,
|
|
169
|
+
{ headers: { 'Authorization': `Bearer ${token}` } }
|
|
170
|
+
);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**After (Merchant API):**
|
|
174
|
+
```javascript
|
|
175
|
+
// Insert product input
|
|
176
|
+
const response = await fetch(
|
|
177
|
+
`https://merchantapi.googleapis.com/products/v1/accounts/${MERCHANT_ID}/productInputs:insert?dataSource=accounts/${MERCHANT_ID}/dataSources/${DS_ID}`,
|
|
178
|
+
{
|
|
179
|
+
method: 'POST',
|
|
180
|
+
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
181
|
+
body: JSON.stringify({
|
|
182
|
+
offerId: 'SKU-001',
|
|
183
|
+
contentLanguage: 'en',
|
|
184
|
+
feedLabel: 'US',
|
|
185
|
+
productAttributes: {
|
|
186
|
+
title: 'Premium Headphones',
|
|
187
|
+
description: 'Great headphones',
|
|
188
|
+
link: 'https://example.com/product',
|
|
189
|
+
imageLink: 'https://example.com/image.jpg',
|
|
190
|
+
availability: 'in_stock',
|
|
191
|
+
condition: 'new',
|
|
192
|
+
price: { amountMicros: '79990000', currencyCode: 'USD' },
|
|
193
|
+
brand: 'AudioBrand',
|
|
194
|
+
gtin: '0123456789012',
|
|
195
|
+
channel: 'ONLINE',
|
|
196
|
+
},
|
|
197
|
+
}),
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
// Get product (includes status)
|
|
202
|
+
const product = await fetch(
|
|
203
|
+
`https://merchantapi.googleapis.com/products/v1/accounts/${MERCHANT_ID}/products/en~US~SKU-001`,
|
|
204
|
+
{ headers: { 'Authorization': `Bearer ${token}` } }
|
|
205
|
+
);
|
|
206
|
+
// product.productStatus contains destinationStatuses and itemLevelIssues
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Price Conversion Helper
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
// Content API price → Merchant API price
|
|
213
|
+
function toMerchantPrice(contentPrice) {
|
|
214
|
+
return {
|
|
215
|
+
amountMicros: String(Math.round(parseFloat(contentPrice.value) * 1_000_000)),
|
|
216
|
+
currencyCode: contentPrice.currency,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Merchant API price → Content API price
|
|
221
|
+
function toContentPrice(merchantPrice) {
|
|
222
|
+
return {
|
|
223
|
+
value: String(parseInt(merchantPrice.amountMicros) / 1_000_000),
|
|
224
|
+
currency: merchantPrice.currencyCode,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
# Content API price → Merchant API price
|
|
231
|
+
def to_merchant_price(content_price):
|
|
232
|
+
return {
|
|
233
|
+
'amountMicros': str(round(float(content_price['value']) * 1_000_000)),
|
|
234
|
+
'currencyCode': content_price['currency'],
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
# Merchant API price → Content API price
|
|
238
|
+
def to_content_price(merchant_price):
|
|
239
|
+
return {
|
|
240
|
+
'value': str(int(merchant_price['amountMicros']) / 1_000_000),
|
|
241
|
+
'currency': merchant_price['currencyCode'],
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Product ID Conversion
|
|
246
|
+
|
|
247
|
+
```javascript
|
|
248
|
+
// Content API ID → Merchant API name
|
|
249
|
+
function toMerchantProductName(contentId, accountId) {
|
|
250
|
+
// contentId format: "online:en:US:sku123"
|
|
251
|
+
const [channel, lang, country, ...offerId] = contentId.split(':');
|
|
252
|
+
const offer = offerId.join(':');
|
|
253
|
+
const prefix = channel === 'local' ? 'local~' : '';
|
|
254
|
+
return `accounts/${accountId}/products/${prefix}${lang}~${country}~${offer}`;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Merchant API name → Content API ID
|
|
258
|
+
function toContentProductId(merchantName) {
|
|
259
|
+
// merchantName: "accounts/123/products/en~US~sku123"
|
|
260
|
+
const productPart = merchantName.split('/products/')[1];
|
|
261
|
+
const isLocal = productPart.startsWith('local~');
|
|
262
|
+
const parts = (isLocal ? productPart.slice(6) : productPart).split('~');
|
|
263
|
+
const [lang, feedLabel, ...offerId] = parts;
|
|
264
|
+
const channel = isLocal ? 'local' : 'online';
|
|
265
|
+
return `${channel}:${lang}:${feedLabel}:${offerId.join('~')}`;
|
|
266
|
+
}
|
|
267
|
+
```
|