The storefront's own description of itself
GET
/api/storefront/{brandId}No keyCallable anonymously. Rate limited by IP.10 requests a minute
Includes a `catalogue` block that may say `present: false` with a reason even when products exist, for example when every item is a development-store sample. That is a judgement about whether an agent should treat this as a shop, and it is deliberately more conservative than a row count.
Parameters
brandIdstring · pathrequiredThe storefront's brand id. There is no public endpoint that maps a domain to a brand id; ask the merchant for their storefront URL, the id is in it.Request
bash
BRAND_ID=cmqmr1f6j0003la04nu93f4k4
curl "https://cresva.ai/api/storefront/$BRAND_ID"Response
Captured from production on 2026-09-16: 200 in 430ms, X-OSP-Version: 2026-03-01. This is what the endpoint returned, not an example of what it might.
JSON
{
"brand_id": "cmqmr1f6j0003la04nu93f4k4",
"brand_name": "Cresva",
"storefront_url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4",
"manifest_url": "https://cresva.ai/.well-known/osp.json?brand=cmqmr1f6j0003la04nu93f4k4",
"supported_currencies": [
"USD"
],
"catalogue": {
"product_count": 0,
"present": false,
"reason": "15 of 15 products are Shopify's development-store samples, so this is a test store rather than a merchant catalogue."
},
"capabilities": [
"search",
"recommend",
"compare",
"negotiate"
],
"endpoints": [
{
"name": "search",
"method": "GET",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/search",
"capability": "search",
"description": "Keyword search across this brand's catalogue."
},
{
"name": "recommend",
"method": "GET",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/recommend",
"capability": "recommend",
"description": "Ranked recommendations for a described need."
},
{
"name": "compare",
"method": "GET",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/compare",
"capability": "compare",
"description": "Attribute comparison across named products."
},
{
"name": "negotiate",
"method": "POST",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/negotiate",
"capability": "negotiate",
"description": "Open a price or terms negotiation for a cart."
},
{
"name": "products",
"method": "GET",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/products",
"description": "Paginated product cards."
},
{
"name": "offers",
"method": "GET",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/offers",
"description": "Live offers and promotions."
},
{
"name": "bundles",
"method": "GET",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/bundles",
"description": "Bundled product groupings."
},
{
"name": "pricing",
"method": "POST",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/pricing",
"description": "Quote pricing for a specific basket."
},
{
"name": "query",
"method": "POST",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/query",
"description": "Natural language query over the catalogue."
},
{
"name": "discovery",
"method": "GET",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/discovery",
"description": "ACP discovery document for this brand."
},
{
"name": "certification",
"method": "GET",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/certification",
"description": "Certification level and issued certificates."
},
{
"name": "trust",
"method": "GET",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/trust",
"description": "Trust score, tier, and its components."
},
{
"name": "feedback",
"method": "POST",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/feedback",
"description": "Submit agent feedback on a result."
},
{
"name": "docs",
"method": "GET",
"url": "https://cresva.ai/api/storefront/cmqmr1f6j0003la04nu93f4k4/docs",
"description": "Human readable documentation for this storefront."
}
]
}Response codes
200The storefront descriptor.object401The key does not match any active key.erroranyTwo shapes exist across this API and that is deliberate rather than untidy. Each route kept the error shape it already used, so an existing client's error handling keeps working. See x-cresva-error-shapes.403The key is valid but belongs to a different brand than the one in the path. Keys are scoped to one brand and do not travel.erroranyTwo shapes exist across this API and that is deliberate rather than untidy. Each route kept the error shape it already used, so an existing client's error handling keeps working. See x-cresva-error-shapes.404No such brand.erroranyTwo shapes exist across this API and that is deliberate rather than untidy. Each route kept the error shape it already used, so an existing client's error handling keeps working. See x-cresva-error-shapes.429Over the rate limit.erroranyTwo shapes exist across this API and that is deliberate rather than untidy. Each route kept the error shape it already used, so an existing client's error handling keeps working. See x-cresva-error-shapes.503The rate limiter could not be reached, so the request was refused rather than served unmetered. Deliberately not a 429: the caller has done nothing wrong and the fault is ours.erroranyTwo shapes exist across this API and that is deliberate rather than untidy. Each route kept the error shape it already used, so an existing client's error handling keeps working. See x-cresva-error-shapes.Generated from the storefront OpenAPI document at growthagents 269d7898b, sha256 047fe4d301258100. Nothing on this page was typed by hand.