Install
openclaw skills install @scavio-ai/scavio-google-shoppingSearch Google Shopping for products, fetch a full product page, and page through every store selling a product — as structured JSON. Price, seller, rating, and price/sale filters. v2 engine, 1 credit per request.
openclaw skills install @scavio-ai/scavio-google-shoppingSearch Google Shopping for products, open a full product detail page, and page through every store selling it — all as structured JSON. Three endpoints, each 1 credit.
Use this skill when the user asks to:
Get a free API key at https://scavio.dev (50 free credits to get started, no card required):
export SCAVIO_API_KEY=sk_live_your_key
| Endpoint | Credits | Description |
|---|---|---|
POST https://api.scavio.dev/api/v2/google/shopping | 1 | Search products, returns shopping_results[] |
POST https://api.scavio.dev/api/v2/google/shopping/product | 1 | Full product detail page |
POST https://api.scavio.dev/api/v2/google/shopping/product/stores | 1 | Page through all stores selling a product |
Authorization: Bearer $SCAVIO_API_KEY
/shopping with a query. Filter with min_price, max_price, on_sale, free_shipping, or sort_by. Each result carries a catalog_id (durable) or product_id./shopping/product with a catalog_id (pass the same query) for full specs, variants, and top stores in product_results./shopping/product/stores with the catalog_id and the next_page_token from the previous response to page through every store.| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | required | Search query (1-500 chars) |
device | string | -- | desktop or mobile |
start | number | -- | Result offset (follow pagination.next) |
min_price | number | -- | Minimum price filter |
max_price | number | -- | Maximum price filter |
sort_by | number | 0 | 0 relevance, 1 price ascending, 2 price descending |
free_shipping | boolean | -- | Only free-shipping offers |
on_sale | boolean | -- | Only on-sale offers |
shoprs | string | -- | Opaque filter token from filters[] / carousel_filters[] |
hl | string | -- | UI language |
gl | string | -- | Geo country |
google_domain | string | google.com | Regional Google domain |
location | string | -- | Canonical location name (auto-UULE) |
uule | string | -- | Pre-encoded UULE |
| Parameter | Type | Default | Description |
|---|---|---|---|
catalog_id | string | -- | Durable catalog id (pass with query) |
query | string | -- | Required when catalog_id is set |
product_id | string | -- | Product id alternative |
immersive_product_page_token | string | -- | Page token from a listing |
page_token | string | -- | Alias for immersive_product_page_token |
device | string | -- | desktop, mobile, or tablet |
sort_by | string | -- | Seller sort: base_price, total_price, promotion, seller_rating |
load_all_stores | boolean | -- | Load all stores inline |
more_stores | boolean | -- | Include additional stores |
hl | string | -- | UI language |
gl | string | -- | Geo country |
google_domain | string | google.com | Regional Google domain |
location | string | -- | Canonical location name |
uule | string | -- | Pre-encoded UULE |
| Parameter | Type | Default | Description |
|---|---|---|---|
catalog_id | string | required | Same catalog_id used on the product call |
next_page_token | string | required | Continuation cursor from a prior response |
import os, requests
BASE = "https://api.scavio.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['SCAVIO_API_KEY']}"}
# 1. Search products, cheapest first, under $1500
search = requests.post(f"{BASE}/api/v2/google/shopping", headers=HEADERS,
json={"query": "16 inch laptop", "sort_by": 1, "max_price": 1500}).json()
item = search["shopping_results"][0]
print(item["title"], item.get("price"), item.get("source"))
# 2. Full product page (catalog_id needs the query alongside it)
product = requests.post(f"{BASE}/api/v2/google/shopping/product", headers=HEADERS,
json={"catalog_id": item["catalog_id"], "query": "16 inch laptop"}).json()
# 3. Page through every store selling it
token = product["product_results"].get("stores_pagination", {}).get("next_page_token")
if token:
stores = requests.post(f"{BASE}/api/v2/google/shopping/product/stores", headers=HEADERS,
json={"catalog_id": item["catalog_id"], "next_page_token": token}).json()
for s in stores["product_results"]["stores"]:
print(s.get("name"), s.get("total_price"))
Search returns shopping_results[] (plus filters and pagination); product returns product_results; stores returns product_results.stores[]. Each also includes response_time, credits_used, credits_remaining, and cached.
{
"shopping_results": [
{
"position": 1,
"title": "Example 16\" Laptop",
"price": "$1,299.00",
"extracted_price": 1299,
"source": "Example Store",
"rating": 4.5,
"reviews": 210,
"catalog_id": "1234567890"
}
],
"response_time": 1420,
"credits_used": 1,
"credits_remaining": 997,
"cached": false
}
catalog_id + query together; the stores call needs catalog_id + next_page_token — always run /shopping first to obtain the catalog_id.extracted_price when present for numeric comparisons.400 means an invalid parameter (e.g. catalog_id without query) — fix and retry.401 means the API key is invalid or missing. Check SCAVIO_API_KEY.429 means rate or usage limit exceeded. Wait before retrying. See https://scavio.dev/docs/rate-limits.502 / 503 mean upstream is temporarily unavailable. Wait a few seconds before retrying.SCAVIO_API_KEY is not set, prompt the user to export it before continuing.