Google Merchant Center
Google Merchant Center API integration with managed OAuth. Manage products, inventories, data sources, promotions, and reports for Google Shopping. Use this...
Google Merchant Center API integration with managed OAuth. Manage products, inventories, data sources, promotions, and reports for Google Shopping. Use this...
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
Access the Google Merchant Center API with managed OAuth authentication. Manage products, inventories, promotions, data sources, and reports for Google Shopping.
# 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
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{version} with v1{accountId} with your Merchant Center account IDThe gateway proxies requests to
merchantapi.googleapis.com and automatically injects your OAuth token.
Important: The v1 API requires one-time developer registration. See Developer Registration section.
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"
Your Merchant Center account ID is a numeric identifier. To find it:
https://merchants.google.com/mc/overview?a=ACCOUNT_IDImportant: Before using the v1 API, you must complete a one-time developer registration to associate your account with the API.
Option A: Try fetching via API first
Try listing accounts using the v1beta endpoint. If this works, you can get your account ID automatically:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/google-merchant/accounts/v1beta/accounts') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') try: result = json.load(urllib.request.urlopen(req)) for account in result.get('accounts', []): print(f"Account ID: {account['accountId']}, Name: {account['accountName']}") except Exception as e: print(f"v1beta not available - use Option B to get your account ID manually") EOF
Option B: From Merchant Center UI (if Option A fails)
If the v1beta endpoint is unavailable or returns an error:
https://merchants.google.com/mc/overview?a=YOUR_ACCOUNT_IDFor example, if your URL is
https://merchants.google.com/mc/overview?a=123456789, your account ID is 123456789.
Call the
registerGcp endpoint with your account ID and email:
python <<'EOF' import urllib.request, os, jsonaccount_id = 'YOUR_ACCOUNT_ID' # From Step 1 developer_email = 'your-email@example.com' # Your Google account email
data = json.dumps({'developerEmail': developer_email}).encode() req = urllib.request.Request( f'https://gateway.maton.ai/google-merchant/accounts/v1/accounts/{account_id}/developerRegistration:registerGcp', data=data, method='POST' ) req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json')
result = json.load(urllib.request.urlopen(req)) print(json.dumps(result, indent=2)) EOF
Response:
{ "name": "accounts/123456789/developerRegistration", "gcpIds": ["216141799266"] }
After registration, v1 endpoints will work:
python <<'EOF' import urllib.request, os, json account_id = 'YOUR_ACCOUNT_ID' req = urllib.request.Request(f'https://gateway.maton.ai/google-merchant/accounts/v1/accounts/{account_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Note: Registration only needs to be done once per Merchant Center account. After registration, all v1 endpoints will work for that account.
Manage your Google Merchant OAuth connections at
https://ctrl.maton.ai.
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
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
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.
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
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.
The Merchant API is organized into sub-APIs:
| Sub-API | Purpose | Version |
|---|---|---|
| Product catalog management | v1 |
| Account settings and users | v1 |
| Data source configuration | v1 |
| Analytics and reporting | v1 |
| Promotional offers (requires enrollment) | v1 |
| Local and regional inventory | v1 |
| Webhook subscriptions | v1 |
| Conversion tracking | v1 |
GET /google-merchant/accounts/v1/accounts
Returns all Merchant Center accounts accessible with your OAuth credentials. Use this to find your account ID.
GET /google-merchant/accounts/v1/accounts/{accountId}
GET /google-merchant/accounts/v1/accounts/{accountId}:listSubaccounts
Note: This endpoint only works for multi-client accounts (MCAs). Standard merchant accounts will receive a 403 error.
GET /google-merchant/accounts/v1/accounts/{accountId}/businessInfo
PATCH /google-merchant/accounts/v1/accounts/{accountId}/businessInfo?updateMask=customerService Content-Type: application/json{ "customerService": { "email": "support@example.com" } }
GET /google-merchant/accounts/v1/accounts/{accountId}/homepage
GET /google-merchant/accounts/v1/accounts/{accountId}/shippingSettings
POST /google-merchant/accounts/v1/accounts/{accountId}/shippingSettings:insert Content-Type: application/json{ "services": [ { "serviceName": "Standard Shipping", "deliveryCountries": ["US"], "currencyCode": "USD", "deliveryTime": { "minTransitDays": 3, "maxTransitDays": 7, "minHandlingDays": 0, "maxHandlingDays": 1 }, "rateGroups": [ { "singleValue": { "flatRate": { "amountMicros": "0", "currencyCode": "USD" } } } ], "active": true } ] }
GET /google-merchant/accounts/v1/accounts/{accountId}/users
GET /google-merchant/accounts/v1/accounts/{accountId}/users/{email}
GET /google-merchant/accounts/v1/accounts/{accountId}/programs
GET /google-merchant/accounts/v1/accounts/{accountId}/regions
GET /google-merchant/accounts/v1/accounts/{accountId}/issues
GET /google-merchant/accounts/v1/accounts/{accountId}/onlineReturnPolicies
GET /google-merchant/products/v1/accounts/{accountId}/products
Query parameters:
pageSize (integer): Maximum results per pagepageToken (string): Pagination tokenGET /google-merchant/products/v1/accounts/{accountId}/products/{productId}
Product ID format:
contentLanguage~feedLabel~offerId (e.g., en~US~sku123)
POST /google-merchant/products/v1/accounts/{accountId}/productInputs:insert?dataSource=accounts/{accountId}/dataSources/{dataSourceId} Content-Type: application/json{ "offerId": "sku123", "contentLanguage": "en", "feedLabel": "US", "productAttributes": { "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" } }
Note: Products can only be inserted into data sources with
input: "API" type. Create an API data source first if needed.
DELETE /google-merchant/products/v1/accounts/{accountId}/productInputs/{productId}?dataSource=accounts/{accountId}/dataSources/{dataSourceId}
GET /google-merchant/inventories/v1/accounts/{accountId}/products/{productId}/localInventories
Note: Local inventories are only available for products with
LOCAL channel. Use a product ID like local~en~US~sku123.
POST /google-merchant/inventories/v1/accounts/{accountId}/products/{productId}/localInventories:insert Content-Type: application/json{ "storeCode": "store123" }
Note: The
storeCode must be a valid store code configured in your Merchant Center account. Additional inventory attributes may be available - refer to the Google Merchant API Reference for the complete field list.
GET /google-merchant/inventories/v1/accounts/{accountId}/products/{productId}/regionalInventories
GET /google-merchant/datasources/v1/accounts/{accountId}/dataSources
GET /google-merchant/datasources/v1/accounts/{accountId}/dataSources/{dataSourceId}
POST /google-merchant/datasources/v1/accounts/{accountId}/dataSources Content-Type: application/json{ "displayName": "API Data Source", "primaryProductDataSource": { "feedLabel": "US", "contentLanguage": "en" } }
Response:
{ "name": "accounts/123456/dataSources/789", "dataSourceId": "789", "displayName": "API Data Source", "primaryProductDataSource": { "feedLabel": "US", "contentLanguage": "en" }, "input": "API" }
PATCH /google-merchant/datasources/v1/accounts/{accountId}/dataSources/{dataSourceId}?updateMask=displayName Content-Type: application/json{ "displayName": "Updated Name" }
DELETE /google-merchant/datasources/v1/accounts/{accountId}/dataSources/{dataSourceId}
POST /google-merchant/datasources/v1/accounts/{accountId}/dataSources/{dataSourceId}:fetch
Note: Fetch only works for data sources with
FILE input type. API and UI data sources cannot be fetched.
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'" }
Example: Query product_view (requires
field):id
{ "query": "SELECT id, offer_id, title, item_issues FROM product_view LIMIT 10" }
Note: The
product_view table requires the id field in the SELECT clause.
Available report tables:
product_performance_view - Clicks, impressions, CTR by productproduct_view - Current inventory with attributes and issues (requires id in SELECT)price_competitiveness_product_view - Pricing vs competitors (requires Market Insights)price_insights_product_view - Suggested pricingbest_sellers_product_cluster_view - Best sellers by category (requires Market Insights)competitive_visibility_competitor_view - Competitor visibilityNote: Promotions require your Merchant Center account to be enrolled in the Promotions program. You'll receive a 403 error if not enrolled.
GET /google-merchant/promotions/v1/accounts/{accountId}/promotions
GET /google-merchant/promotions/v1/accounts/{accountId}/promotions/{promotionId}
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" } }
GET /google-merchant/notifications/v1/accounts/{accountId}/notificationsubscriptions
POST /google-merchant/notifications/v1/accounts/{accountId}/notificationsubscriptions Content-Type: application/json{ "registeredEvent": "PRODUCT_STATUS_CHANGE", "callBackUri": "https://example.com/webhook", "allManagedAccounts": true }
Note: You must specify either
allManagedAccounts: true OR targetAccount: "accounts/{accountId}" to indicate which accounts the subscription applies to.
Alternative with targetAccount:
{ "registeredEvent": "PRODUCT_STATUS_CHANGE", "callBackUri": "https://example.com/webhook", "targetAccount": "accounts/123456789" }
DELETE /google-merchant/notifications/v1/accounts/{accountId}/notificationsubscriptions/{subscriptionId}
GET /google-merchant/conversions/v1/accounts/{accountId}/conversionSources
POST /google-merchant/conversions/v1/accounts/{accountId}/conversionSources Content-Type: application/json{ "merchantCenterDestination": { "displayName": "My Conversion Source", "destination": "SHOPPING_ADS", "currencyCode": "USD", "attributionSettings": { "attributionLookbackWindowDays": 30, "attributionModel": "CROSS_CHANNEL_LAST_CLICK" } } }
DELETE /google-merchant/conversions/v1/accounts/{accountId}/conversionSources/{conversionSourceId}
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...
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();
import os import requestsaccount_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()
contentLanguage~feedLabel~offerId (e.g., en~US~sku123)input: "API" typeLOCAL channel (not ONLINE)curl -g when URLs contain brackets to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|---|---|
| 400 | Invalid request or missing Google Merchant connection |
| 401 | Invalid/missing Maton API key, or GCP project not registered (see Developer Registration) |
| 403 | Permission denied - account not enrolled in required program or feature not available |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Google Merchant API |
"GCP project is not registered": You need to complete developer registration. See Developer Registration section.
"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.
"Promotion program not enabled": Your Merchant Center account is not enrolled in the Promotions program. Enable it in Merchant Center settings.
"This method can only be accessed by multi-client accounts": You're calling an endpoint (like listSubaccounts) that only works for multi-client accounts (MCAs).
"Mismatched channel": You're trying to access local inventories for an ONLINE product. Local inventories only work with LOCAL channel products.
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Ensure your URL path starts with
google-merchant. For example:
https://gateway.maton.ai/google-merchant/products/v1/accounts/{accountId}/productshttps://gateway.maton.ai/products/v1/accounts/{accountId}/productsIf you see an error like "GCP project is not registered with the merchant account":
?a=)registerGcp endpoint with your account ID and emailNo automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.