🎁 Get the FREE AI Skills Starter GuideSubscribe →
BytesAgainBytesAgain
🦀 ClawHub

Google Merchant Center

by @byungkyu

Google Merchant Center API integration with managed OAuth. This is a write-capable integration — it can read, create, update, and delete products, inventorie...

Versionv1.0.7
Downloads5,980
Installs4
Stars5
TERMINAL
clawhub install google-merchant

📖 About This Skill


name: google-merchant description: | Google Merchant Center API integration with managed OAuth. This is a write-capable integration — it can read, create, update, and delete products, inventories, data sources, promotions, account settings, and conversions in Google Shopping. Use this skill when users want to interact with their Merchant Center data. All write operations (creating/updating/deleting products, inventories, promotions, data sources, or account settings) require explicit user approval with specific resource identifiers before execution. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key. metadata: author: maton version: "1.0" clawdbot: emoji: 🧠 requires: env: - MATON_API_KEY

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://api.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://api.maton.ai/google-merchant/{sub-api}/{version}/accounts/{accountId}/{resource}

The Merchant API uses a modular sub-API structure:

  • {sub-api} — the service module: products, accounts, datasources, reports, promotions, inventories, notifications, conversions
  • {version} — currently v1
  • {accountId} — your Merchant Center account ID
  • Maton 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.

    Authentication

    All requests require the Maton API key in the Authorization header:

    Authorization: Bearer $MATON_API_KEY
    

    IMPORTANT: Treat MATON_API_KEY as a secret — do not log it, include it in chats or prompts visible to others, or expose it in shared files or outputs. The key authenticates with Maton, and the Google Merchant connection is independently scoped via OAuth. Use least-privilege Google Merchant access, revoke the connection when no longer needed, and if the key is compromised, rotate it immediately at maton.ai/settings.

    Environment Variable: Set your API key as MATON_API_KEY:

    export MATON_API_KEY="YOUR_API_KEY"
    

    Getting Your API Key

    1. Sign in or create an account at maton.ai 2. Go to maton.ai/settings 3. Copy your API key

    Finding Your Merchant Center Account ID

    Your Merchant Center account ID is a numeric identifier. To find it:

    1. Log in to Google Merchant Center 2. Look at the URL - it contains your account ID: https://merchants.google.com/mc/overview?a=ACCOUNT_ID

    Developer Registration

    Important: Before using the v1 API, you must complete a one-time developer registration to associate your account with the API.

    Step 1: Get Your Account ID

    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://api.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:

    1. Log in to Google Merchant Center 2. Your account ID is in the URL: https://merchants.google.com/mc/overview?a=YOUR_ACCOUNT_ID

    For example, if your URL is https://merchants.google.com/mc/overview?a=123456789, your account ID is 123456789.

    Step 2: Register for API Access

    Call the registerGcp endpoint with your account ID and email:

    python <<'EOF'
    import urllib.request, os, json

    account_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://api.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"]
    }
    

    Step 3: Verify Registration

    After registration, v1 endpoints will work:

    python <<'EOF'
    import urllib.request, os, json
    account_id = 'YOUR_ACCOUNT_ID'
    req = urllib.request.Request(f'https://api.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.

    Connection Management

    Manage your Google Merchant OAuth connections at https://api.maton.ai.

    List Connections

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.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://api.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://api.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": "{connection_id}",
        "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://api.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://api.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', '{connection_id}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Always include the Maton-Connection header to ensure requests go to the intended account, especially before any write operation. If you have multiple connections and omit this header, the gateway uses the default connection, which may not be the intended account.

    Security & Permissions

  • Access is scoped to products, inventories, data sources, promotions, account settings, conversions, and reports within the connected Google Merchant Center account. Only install if you need Merchant Center administration. Revoke unused connections promptly.
  • Default to read-only operations. Always start by listing or retrieving resources to confirm identifiers before proposing any changes.
  • All write operations require explicit user approval with specific identifiers. Before executing any POST, PATCH, or DELETE call:
  • 1. Retrieve and display the target resource (product title/ID, data source name, promotion ID) so the user can verify. 2. Clearly describe the intended effect (e.g., "This will delete product 'Blue Widget' (ID: online~en~US~SKU123) from your Merchant Center account"). 3. Wait for explicit user confirmation before proceeding.
  • High-impact operations require extra caution. Modifying product listings, changing data source configurations, updating inventory, or altering account settings can affect live Google Shopping listings and business operations. These actions must include a summary of consequences and require confirmation.
  • API Reference

    Sub-API Structure

    The Merchant API is organized into sub-APIs:

    | Sub-API | Purpose | 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 (requires enrollment) | v1 | | inventories | Local and regional inventory | v1 | | notifications | Webhook subscriptions | v1 | | conversions | Conversion tracking | v1 |

    Accounts

    #### List Accounts

    GET /google-merchant/accounts/v1/accounts
    

    Returns all Merchant Center accounts accessible with your OAuth credentials. Use this to find your account ID.

    #### Get Account

    GET /google-merchant/accounts/v1/accounts/{accountId}
    

    #### List Sub-accounts

    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 Business Info

    GET /google-merchant/accounts/v1/accounts/{accountId}/businessInfo
    

    #### Update Business Info

    PATCH /google-merchant/accounts/v1/accounts/{accountId}/businessInfo?updateMask=customerService
    Content-Type: application/json

    { "customerService": { "email": "support@example.com" } }

    #### Get Homepage

    GET /google-merchant/accounts/v1/accounts/{accountId}/homepage
    

    #### Get Shipping Settings

    GET /google-merchant/accounts/v1/accounts/{accountId}/shippingSettings
    

    #### Insert Shipping Settings

    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 } ] }

    #### List Users

    GET /google-merchant/accounts/v1/accounts/{accountId}/users
    

    #### Get User

    GET /google-merchant/accounts/v1/accounts/{accountId}/users/{email}
    

    #### List Programs

    GET /google-merchant/accounts/v1/accounts/{accountId}/programs
    

    #### List Regions

    GET /google-merchant/accounts/v1/accounts/{accountId}/regions
    

    #### List Account Issues

    GET /google-merchant/accounts/v1/accounts/{accountId}/issues
    

    #### List Online Return Policies

    GET /google-merchant/accounts/v1/accounts/{accountId}/onlineReturnPolicies
    

    Products

    #### List Products

    GET /google-merchant/products/v1/accounts/{accountId}/products
    

    Query parameters:

  • pageSize (integer): Maximum results per page
  • pageToken (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", "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 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
    

    Note: Local inventories are only available for products with LOCAL channel. Use a product ID like local~en~US~sku123.

    #### Insert Local Inventory

    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.

    #### 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": { "feedLabel": "US", "contentLanguage": "en" } }

    Response:

    {
      "name": "accounts/123456/dataSources/789",
      "dataSourceId": "789",
      "displayName": "API Data Source",
      "primaryProductDataSource": {
        "feedLabel": "US",
        "contentLanguage": "en"
      },
      "input": "API"
    }
    

    #### Update Data Source

    PATCH /google-merchant/datasources/v1/accounts/{accountId}/dataSources/{dataSourceId}?updateMask=displayName
    Content-Type: application/json

    { "displayName": "Updated Name" }

    #### Delete Data Source

    DELETE /google-merchant/datasources/v1/accounts/{accountId}/dataSources/{dataSourceId}
    

    #### Fetch Data Source (trigger immediate refresh)

    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.

    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'" }

    Example: Query product_view (requires id field):

    {
      "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 product
  • product_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 pricing
  • best_sellers_product_cluster_view - Best sellers by category (requires Market Insights)
  • competitive_visibility_competitor_view - Competitor visibility
  • Promotions

    Note: Promotions require your Merchant Center account to be enrolled in the Promotions program. You'll receive a 403 error if not enrolled.

    #### 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" } }

    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", "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 Notification Subscription

    DELETE /google-merchant/notifications/v1/accounts/{accountId}/notificationsubscriptions/{subscriptionId}
    

    Conversion Sources

    #### List Conversion Sources

    GET /google-merchant/conversions/v1/accounts/{accountId}/conversionSources
    

    #### Create Conversion Source

    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 Conversion Source

    DELETE /google-merchant/conversions/v1/accounts/{accountId}/conversionSources/{conversionSourceId}
    

    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://api.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://api.maton.ai/google-merchant/products/v1/accounts/{account_id}/products', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'} ) data = response.json()

    Notes

  • Developer registration required - You must complete Developer Registration once per Merchant Center account before using v1 endpoints
  • Product IDs use the format contentLanguage~feedLabel~offerId (e.g., en~US~sku123)
  • Products can only be inserted/updated/deleted in data sources with input: "API" type
  • 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)
  • Local inventories only work for products with LOCAL channel (not ONLINE)
  • The Promotions API requires your account to be enrolled in the Promotions program
  • List Sub-accounts only works for multi-client accounts (MCAs)
  • IMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing
  • IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments
  • Error Handling

    | 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 |

    Common Errors

    "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.

    Troubleshooting: API Key Issues

    1. Check that the MATON_API_KEY environment variable is set:

    echo $MATON_API_KEY
    

    2. Verify the API key is valid by listing connections:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.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
    

    Troubleshooting: Invalid App Name

    Ensure your URL path starts with google-merchant. For example:

  • Correct: https://api.maton.ai/google-merchant/products/v1/accounts/{accountId}/products
  • Incorrect: https://api.maton.ai/products/v1/accounts/{accountId}/products
  • Troubleshooting: 401 GCP Project Not Registered

    If you see an error like "GCP project is not registered with the merchant account":

    1. Complete developer registration - See Developer Registration section 2. Get your account ID from Merchant Center UI (in the URL after ?a=) 3. Call the registerGcp endpoint with your account ID and email 4. After successful registration, retry your original request

    Resources

  • Merchant API Overview
  • Merchant API Reference
  • Products Guide
  • Data Sources Guide
  • Reports Guide
  • Product Data Specification
  • Maton Community
  • Maton Support
  • 💡 Examples

    # List products in your Merchant Center account
    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.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
    

    📋 Tips & Best Practices

  • Developer registration required - You must complete Developer Registration once per Merchant Center account before using v1 endpoints
  • Product IDs use the format contentLanguage~feedLabel~offerId (e.g., en~US~sku123)
  • Products can only be inserted/updated/deleted in data sources with input: "API" type
  • 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)
  • Local inventories only work for products with LOCAL channel (not ONLINE)
  • The Promotions API requires your account to be enrolled in the Promotions program
  • List Sub-accounts only works for multi-client accounts (MCAs)
  • IMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing
  • IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments