google-merchant
This skill integrates with Google Merchant Center via a Maton gateway to manage products, inventories, promotions, and reports. It requires the MATON_API_KEY and includes example commands that call https://gateway.maton.ai and https://ctrl.maton.ai.
Google Merchant Center
Access the Google Merchant Center API with managed OAuth authentication. Manage products, inventories, promotions, data sources, and reports for Google Shopping.
Quick Start
# List products in your Merchant Center account
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/google-merchant/products/v1/accounts/{accountId}/products')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://gateway.maton.ai/google-merchant/{sub-api}/{version}/accounts/{accountId}/{resource}
The Merchant API uses a modular sub-API structure. Replace:
{sub-api}with the service:products,accounts,datasources,reports,promotions,inventories,notifications,conversions,lfp{version}withv1(stable) orv1beta{accountId}with your Merchant Center account ID
The gateway proxies requests to merchantapi.googleapis.com and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Finding Your Merchant Center Account ID
Your Merchant Center account ID is a numeric identifier visible in the Merchant Center UI URL or account settings. It's required for all API calls.
Connection Management
Manage your Google Merchant OAuth connections at https://ctrl.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=google-merchant&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'google-merchant'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "00726960-095e-47e2-92e6-6e9cdf3e40a1",
"status": "ACTIVE",
"creation_time": "2026-02-07T06:41:22.751289Z",
"last_updated_time": "2026-02-07T06:42:29.411979Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "google-merchant",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple Google Merchant connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/google-merchant/products/v1/accounts/123456/products')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '00726960-095e-47e2-92e6-6e9cdf3e40a1')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
API Reference
Sub-API Structure
The Merchant API is organized into sub-APIs, each with its own version:
| Sub-API | Purpose | Stable Version |
|---|---|---|
products | Product catalog management | v1 |
accounts | Account settings and users | v1 |
datasources | Data source configuration | v1 |
reports | Analytics and reporting | v1 |
promotions | Promotional offers | v1 |
inventories | Local and regional inventory | v1 |
notifications | Webhook subscriptions | v1 |
conversions | Conversion tracking | v1 |
lfp | Local Fulfillment Partnership | v1beta |
Products
List Products
GET /google-merchant/products/v1/accounts/{accountId}/products
Query parameters:
pageSize(integer): Maximum results per pagepageToken(string): Pagination token
Get Product
GET /google-merchant/products/v1/accounts/{accountId}/products/{productId}
Product ID format: contentLanguage~feedLabel~offerId (e.g., en~US~sku123)
Insert Product Input
POST /google-merchant/products/v1/accounts/{accountId}/productInputs:insert?dataSource=accounts/{accountId}/dataSources/{dataSourceId}
Content-Type: application/json
{
"offerId": "sku123",
"contentLanguage": "en",
"feedLabel": "US",
"attributes": {
"title": "Product Title",
"description": "Product description",
"link": "https://example.com/product",
"imageLink": "https://example.com/image.jpg",
"availability": "in_stock",
"price": {
"amountMicros": "19990000",
"currencyCode": "USD"
},
"condition": "new"
}
}
Delete Product Input
DELETE /google-merchant/products/v1/accounts/{accountId}/productInputs/{productId}?dataSource=accounts/{accountId}/dataSources/{dataSourceId}
Inventories
List Local Inventories
GET /google-merchant/inventories/v1/accounts/{accountId}/products/{productId}/localInventories
Insert Local Inventory
POST /google-merchant/inventories/v1/accounts/{accountId}/products/{productId}/localInventories:insert
Content-Type: application/json
{
"storeCode": "store123",
"availability": "in_stock",
"quantity": 10,
"price": {
"amountMicros": "19990000",
"currencyCode": "USD"
}
}
List Regional Inventories
GET /google-merchant/inventories/v1/accounts/{accountId}/products/{productId}/regionalInventories
Data Sources
List Data Sources
GET /google-merchant/datasources/v1/accounts/{accountId}/dataSources
Get Data Source
GET /google-merchant/datasources/v1/accounts/{accountId}/dataSources/{dataSourceId}
Create Data Source
POST /google-merchant/datasources/v1/accounts/{accountId}/dataSources
Content-Type: application/json
{
"displayName": "API Data Source",
"primaryProductDataSource": {
"channel": "ONLINE_PRODUCTS",
"feedLabel": "US",
"contentLanguage": "en"
}
}
Fetch Data Source (trigger immediate refresh)
POST /google-merchant/datasources/v1/accounts/{accountId}/dataSources/{dataSourceId}:fetch
Reports
Search Reports
POST /google-merchant/reports/v1/accounts/{accountId}/reports:search
Content-Type: application/json
{
"query": "SELECT offer_id, title, clicks, impressions FROM product_performance_view WHERE date BETWEEN '2026-01-01' AND '2026-01-31'"
}
Available report tables:
product_performance_view- Clicks, impressions, CTR by productproduct_view- Current inventory with attributes and issuesprice_competitiveness_product_view- Pricing vs competitorsprice_insights_product_view- Suggested pricingbest_sellers_product_cluster_view- Best sellers by categorycompetitive_visibility_competitor_view- Competitor visibility
Promotions
List Promotions
GET /google-merchant/promotions/v1/accounts/{accountId}/promotions
Get Promotion
GET /google-merchant/promotions/v1/accounts/{accountId}/promotions/{promotionId}
Insert Promotion
POST /google-merchant/promotions/v1/accounts/{accountId}/promotions:insert
Content-Type: application/json
{
"promotionId": "promo123",
"contentLanguage": "en",
"targetCountry": "US",
"redemptionChannel": ["ONLINE"],
"attributes": {
"longTitle": "20% off all products",
"promotionEffectiveDates": "2026-02-01T00:00:00Z/2026-02-28T23:59:59Z"
}
}
Accounts
Get Account
GET /google-merchant/accounts/v1/accounts/{accountId}
List Sub-accounts
GET /google-merchant/accounts/v1/accounts/{accountId}:listSubaccounts
Get Business Info
GET /google-merchant/accounts/v1/accounts/{accountId}/businessInfo
Get Shipping Settings
GET /google-merchant/accounts/v1/accounts/{accountId}/shippingSettings
List Users
GET /google-merchant/accounts/v1/accounts/{accountId}/users
List Programs
GET /google-merchant/accounts/v1/accounts/{accountId}/programs
List Regions
GET /google-merchant/accounts/v1/accounts/{accountId}/regions
List Online Return Policies
GET /google-merchant/accounts/v1/accounts/{accountId}/onlineReturnPolicies
Notifications
List Notification Subscriptions
GET /google-merchant/notifications/v1/accounts/{accountId}/notificationsubscriptions
Create Notification Subscription
POST /google-merchant/notifications/v1/accounts/{accountId}/notificationsubscriptions
Content-Type: application/json
{
"registeredEvent": "PRODUCT_STATUS_CHANGE",
"callBackUri": "https://example.com/webhook"
}
Conversion Sources
List Conversion Sources
GET /google-merchant/conversions/v1/accounts/{accountId}/conversionSources
Pagination
The API uses token-based pagination:
GET /google-merchant/products/v1/accounts/{accountId}/products?pageSize=50
Response includes nextPageToken when more results exist:
{
"products": [...],
"nextPageToken": "CAE..."
}
Use the token for the next page:
GET /google-merchant/products/v1/accounts/{accountId}/products?pageSize=50&pageToken=CAE...
Code Examples
JavaScript
const accountId = '123456789';
const response = await fetch(
`https://gateway.maton.ai/google-merchant/products/v1/accounts/${accountId}/products`,
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
Python
import os
import requests
account_id = '123456789'
response = requests.get(
f'https://gateway.maton.ai/google-merchant/products/v1/accounts/{account_id}/products',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()
Notes
- Product IDs use the format
contentLanguage~feedLabel~offerId(e.g.,en~US~sku123) - Products can only be inserted/updated/deleted in data sources of type
API - After inserting/updating a product, it may take several minutes before the processed product appears
- Monetary values use micros (divide by 1,000,000 for actual value)
- The API uses sub-API versioning - prefer
v1stable overv1beta - IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing Google Merchant connection |
| 401 | Invalid or missing Maton API key, or no access to specified account |
| 403 | Permission denied for the requested operation |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Google Merchant API |
Common Errors
"The caller does not have access to the accounts": The specified account ID is not accessible with your OAuth credentials. Verify you have access to the Merchant Center account.
"GCP project is not registered": The v1 stable API requires GCP project registration. Use v1beta or register your project.