Products
A storefront's catalogue is read only over OSP. An agent can list it, read one product, search it and compare items in it. Nothing an agent sends can change what a merchant sells.
The catalogue is written by the merchant's own ingestion, from Shopify or from the Cresva dashboard. There is no write path on this API and there is not going to be one: a protocol that let a caller edit a merchant's catalogue would be a protocol a merchant could not safely point at an agent.
/productsList all products. Supports pagination and filtering.
Pagination: page (default 1) and limit (default 20, max 50). There is no perPage, no sorting and no date filtering on this endpoint. See Rate Limits for usage best practices.
Query Parameters
pageintegerPage number. Default 1.limitintegerCards per page. Default 20, maximum 50.# No credential is needed for a catalogue read.
curl "https://cresva.ai/api/storefront/$BRAND_ID/products?limit=10"
# A public key raises the rate limit from 10 a minute to 60.
curl "https://cresva.ai/api/storefront/$BRAND_ID/products?limit=10" \
-H "Authorization: Bearer $CRESVA_PUBLIC_KEY"const res = await fetch("https://cresva.ai/api/storefront/[brandId]/products?status=active", {
headers: { Authorization: "Bearer " + process.env.CRESVA_API_KEY },
});
const { products, meta } = await res.json();/products/{productId}Retrieve a single product by ID.
curl "https://cresva.ai/api/storefront/$BRAND_ID/products/$PRODUCT_ID"const res = await fetch("https://cresva.ai/api/storefront/$BRAND_ID/products/$PRODUCT_ID", {
headers: { Authorization: "Bearer " + process.env.CRESVA_API_KEY },
});
const { data } = await res.json();/searchKeyword search across the catalogue. Returns the same product cards as the list endpoint, plus a meta block describing the answer.
Authentication: none required
qstringThe search terms. Required.limitintegerMaximum cards to return.curl "https://cresva.ai/api/storefront/$BRAND_ID/search?q=snowboard"A search that matches nothing returns 200 with an empty products array. It is not a 404: the catalogue answered, and the answer was that it holds nothing matching.
{
"query": "snowboard",
"products": [ /* product cards */ ],
"meta": {
"total": 1,
"page": 1,
"authority_score": 19.3,
"response_time_ms": 19,
"data_freshness": "2026-09-15T19:13:35.313Z"
}
}/compareCompare two or more products from the same catalogue side by side.
Authentication: none required
idsstringComma separated product ids. Required.This is a GET with a query parameter, not a POST with a body. Earlier drafts of the protocol described a POST and the site documented one; the route has only ever exported GET, so a POST returns 405.
curl "https://cresva.ai/api/storefront/$BRAND_ID/compare?ids=prod_a,prod_b"Product object
{
"id": "cmtpqwhit001ajv04e1vvv5j6",
"title": "The Videographer Snowboard",
"summary": "",
"price": { "amount": 885.95, "currency": "USD", "formatted": "$885.95" },
"availability": "in_stock",
"rating": null,
"attributes": {},
"comparison_context": null,
"purchase_url": "https://cresva-pilot-two.myshopify.com/products/the-videographer-snowboard",
"images": ["https://cdn.shopify.com/s/files/1/0803/1135/3541/files/Main.jpg?v=1787511528"]
}