Skip to main content

Product Alternatives and Details

This example separates an unavailable exact product request from verified alternatives and shows how product-detail requests use chat, a Flow, or direct routed-tool execution.

With a Flow configured for offer_first, an exact miss returns an offer without product cards:

{
"action": "OFFER_PRODUCT_ALTERNATIVES",
"content": "I could not find the exact requested variant. Would you like to see the same model in other colors?",
"session_id": "{{session_id}}",
"data": {
"text": "I could not find the exact requested variant. Would you like to see the same model in other colors?",
"requested_query": "red phone model 17",
"alternative_query": "phone model 17",
"match": {
"exact": false,
"fallback_used": false,
"requested_query": "red phone model 17",
"applied_query": "red phone model 17",
"relaxed_constraints": ["color:red"]
}
},
"trace_id": "trace_example_offer"
}

Send the customer's acceptance through /api/v1/runtime/ai/chat in the same authorized session without flow_id. ACP then executes the saved bounded query and returns RENDER_PRODUCT_ALTERNATIVES with catalog-backed products. The client must preserve the requested query, applied query, and relaxed constraints and must not label the products as exact matches.

Product-Detail Route Selection​

InputEndpointSuccessful contract
Natural-language reference to a recent result/api/v1/runtime/ai/chat without flow_idRENDER_PRODUCT_DETAILS, or CLARIFY without lookup when unresolved
Known selection requiring an ACP action envelope/api/v1/runtime/execute with a protected product-details FlowRuntime execution containing RENDER_PRODUCT_DETAILS
Known widget selection requiring only the tool result/api/v1/runtime/mcp/tools/executeRaw routed-tool result; no runtime action

For the direct widget route, the BFF uses a fixed allowlisted operation-to-tool mapping:

{
"session_id": "{{session_id}}",
"tool_name": "catalog_get_product_details",
"arguments": {
"catalogId": "1234567890"
},
"strategy": "first_healthy"
}

A successful response has the routed-tool envelope:

{
"mcp_server_id": "{{selected_mcp_server_id}}",
"tool_name": "catalog_get_product_details",
"result": {
"success": true,
"data": {
"catalogId": "1234567890",
"name": "Phone Model 17",
"price": "1299.99",
"currency": "USD",
"inStock": true
}
}
}

The BFF validates the expected tool name and returned identifier before mapping result.data to its product-detail view. The browser/mobile client supplies only the selected product identifier to the BFF; it never supplies tool_name, MCP server IDs, or flow_id. Do not run both deterministic routes for the same selection.