Search products
Find products from shopping needs, keywords, a model or a product identifier.
What this endpoint does
Endpoint
```
POST https://mcp.gaisho.co/v1/tools/search_products
```Find candidates from a shopper’s requirements, a known model or a product identifier. Use this as the discovery step when the shopper has not selected a product, then carry the returned product and offer IDs into detail checks and purchase comparisons.
- Find a cordless vacuum under $300 with the shopper’s required features.
- Look up an exact model, product link, ASIN or GTIN.
- Compare explicitly accepted alternatives in one request.
Before you call
- Include the product type, hard requirements, exact sizes or quantities, exclusions and any stated USD budget. Preserve comparison directions such as at least or under.
- Mark optional wishes as preferred. Use or for accepted alternatives. Do not add a brand, budget or specification the shopper did not request.
- Keep requests about answer style or research process outside query. A request to report battery life is different from a requirement for at least 30 hours of battery life.
- Put specifications and budget in query by default. filters requires the query to resolve to a single indexed product type; a broad category or identifier lookup cannot use it. price_min and price_max are USD amounts, min_rating is a rating threshold and min_reviews is a review-count threshold. The overview does not provide a complete attribute-key mapping, so do not guess additional keys. Pagination and an arbitrary result limit are not published inputs.
Send a JSON object as the request body and authenticate with Authorization: Bearer <API key>. Amounts are in USD unless the result explicitly says otherwise.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| query | string | Required | Shopping requirements, keywords or a model. Include only the shopper’s stated needs and budget. |
| filters | object | Optional | Optional filters for a query resolving to one indexed product type. Documented keys: price_min, price_max (USD), min_rating and min_reviews. Prefer putting requirements in query; do not guess attribute keys from overview labels. Not supported for URL or identifier lookups. |
Example request
Set GAISHO_API_KEY in your server or local environment. These examples use a JSON POST request; Python uses the standard library and JavaScript uses Node.js fetch. The 60-second client timeout in Python and JavaScript is configurable, not a service latency guarantee.
cURL
```
curl --fail-with-body 'https://mcp.gaisho.co/v1/tools/search_products' \
-H "Authorization: Bearer $GAISHO_API_KEY" \
-H 'Content-Type: application/json' \
--data '{
"query": "cordless vacuum under $300"
}'
```Python
```
import json
import os
import urllib.error
import urllib.request
arguments = json.loads(r'''{
"query": "cordless vacuum under $300"
}''')
request = urllib.request.Request(
"https://mcp.gaisho.co/v1/tools/search_products",
data=json.dumps(arguments).encode("utf-8"),
headers={
"Authorization": "Bearer " + os.environ["GAISHO_API_KEY"],
"Content-Type": "application/json",
},
method="POST",
)
try:
with urllib.request.urlopen(request, timeout=60) as response:
payload = json.load(response)
print(json.dumps(payload, indent=2))
except urllib.error.HTTPError as error:
print(error.read().decode("utf-8"))
raise
```JavaScript
```
// Node.js 18+; keep this code and the key on your server.
const response = await fetch("https://mcp.gaisho.co/v1/tools/search_products", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GAISHO_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"query": "cordless vacuum under $300"
}),
signal: AbortSignal.timeout(60_000),
});
const body = await response.text();
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${body}`);
}
const payload = JSON.parse(body);
console.log(payload);
```Common request patterns
Required features and a preference
Battery life and budget remain requirements; color is optional.
JSON request body
```
{
"query": "Over-ear noise-cancelling headphones under $200, battery life at least 30 hours, black preferred"
}
```Apply an explicit budget filter
Use filters only when the query resolves to an indexed product type. Otherwise include the budget in query and omit filters.
JSON request body
```
{
"query": "cordless stick vacuum",
"filters": {
"price_max": 300
}
}
```Response fields
The HTTP response contains tool and summary. Product information is carried in summary text; there is no separate structured result array. Treat its wording as readable content, not a fixed column schema.
| Field | Type | Description |
|---|---|---|
| tool | string | The tool called: search_products. |
| summary | string | Match count, interpreted requirements and product candidates with identifiers, prices and links. |
Example response
Examples are illustrative and may omit optional detail fields. Prices are not live quotes; identifiers and example.com URLs are placeholders to replace, not usable product records.
HTTP 200 · illustrative, shortened
```
{
"tool": "search_products",
"summary": "Products matching cordless vacuum under $300.\nExample cordless vacuum — $179.99\nproduct_id: PRODUCT_ID_FROM_SEARCH\noffer_id: OFFER_ID_FROM_SEARCH\nPurchase link: https://example.com/vacuum\nCheck the product details for specifications and other offers."
}
```How to read the result
- The public response is summary text containing the interpreted requirements, up to 15 candidates and their identifiers. There is no separate results array on this endpoint.
- Distinguish products that meet the applied conditions from products that state too little to verify them. Missing detail is not evidence that a required feature is present.
- When more products match than are shown, read the refinement guidance to narrow the request. Explicit highest-rated or most-reviewed ordering requests are supported. A product_id refers to a product; an offer_id refers to a particular listing. Keep the listing’s price, seller and purchase URL together when making a recommendation.
Empty results and errors
| Situation | How to handle it |
|---|---|
| No suitable candidates | Check the interpreted requirements. Ask the shopper before relaxing a required feature or changing their budget. |
| A requirement is unresolved | Use product or offer details to investigate it and disclose that it remains unverified if the information is absent. |
| Unknown filter key | Remove the guessed key and put the requirement in query. For explicit filters, use documented keys and a query that resolves to an indexed product type. |
A successful request can return no candidates, missing information or an unavailable assessment. Check the result before recommending a product. For request failures, use the error code and message; retrying the same invalid input will not fix it.
- [Error handling and retries](https://gaisho.co/docs/api#errors): HTTP statuses, structured errors, rate limits and quota responses.
What to call next
- [Get product details](https://gaisho.co/docs/api/get_product): Read product specifications, ratings, reviews and offers, for one product or up to eight at once.
- [Get offer details](https://gaisho.co/docs/api/get_offer): Read a listing’s purchase URL, seller, price, coupon terms and stated product information.
- [Compare purchase options](https://gaisho.co/docs/api/find_deals): Find offers for the same product, compatible alternatives, or models with specification upgrades and downgrades.
- [Use this tool through MCP](https://gaisho.co/docs/mcp/search_products): The same capability through the other connection.
- [REST API conventions](https://gaisho.co/docs/api): Authentication, response envelopes and request handling.