Conversations and conversion
Guided selling is not yet available. This page describes it ahead of its release, so details can still change. The changelog announces when it is released.
Guided selling records every conversation: each step as the customer saw it, the model calls behind it and what the storefront reported about the advice. The statistics show how a flow converts and the history shows why. Recorded conversations are kept for a year.
Measuring conversion
guidedSellingFlowStats counts the conversations of a flow:
query FlowStats($flowId: ID!, $input: GuidedSellingFlowStatsInput) {
guidedSellingFlowStats(flowId: $flowId, input: $input) {
flowId
version
conversations
adviceReached
converted
productsConverted
}
}
Variables:
{
"flowId": "01a10f3c-5b7e-7d42-9a61-3c8e2f4b7d90",
"input": {
"version": 1,
"createdAt": { "greaterThan": "2026-10-01T00:00:00Z" }
}
}
Expected response:
{
"data": {
"guidedSellingFlowStats": {
"flowId": "01a10f3c-5b7e-7d42-9a61-3c8e2f4b7d90",
"version": 1,
"conversations": 412,
"adviceReached": 287,
"converted": 64,
"productsConverted": 91
}
}
}
| Field | What it counts |
|---|---|
conversations | Conversations that started |
adviceReached | Conversations that reached the advice. An advice that guided selling served counts as seen. |
converted | Conversations that reached the advice and in which the customer converted an advised product: added it to the cart, requested a quote, downloaded its documents or anything else the storefront counts as a conversion |
productsConverted | Advised products converted, each advised product once per conversation, however often or in what quantity the storefront reported it |
Every count except productsConverted is a number of conversations. converted and productsConverted depend on the storefront reporting conversions, see Reporting outcomes.
Both filters in input are optional. version counts only conversations that started on that version, which lets you compare versions. createdAt selects conversations by the moment of their first step. Conversations you run to test a draft count toward that version too. A conversation counts for the flow it started on, and only there: a step for another flow with the same conversationId is refused.
Conversion of every flow in a list
To show the figures next to each flow in a list, select stats on the flows of guidedSellingFlows. Guided selling counts the whole page at once, so a list of flows never needs a guidedSellingFlowStats call per flow. stats counts all versions of the flow and takes the same optional createdAt window:
query FlowsWithStats($input: GuidedSellingFlowSearchInput, $createdAt: DateSearchInput) {
guidedSellingFlows(input: $input) {
items {
id
name
stats(createdAt: $createdAt) {
conversations
adviceReached
converted
productsConverted
}
}
}
}
Variables:
{
"input": { "page": 1, "offset": 12 },
"createdAt": { "greaterThan": "2026-10-01T00:00:00Z" }
}
Expected response:
{
"data": {
"guidedSellingFlows": {
"items": [
{
"id": "01a10f3c-5b7e-7d42-9a61-3c8e2f4b7d90",
"name": "Label printer advisor",
"stats": {
"conversations": 498,
"adviceReached": 351,
"converted": 77,
"productsConverted": 109
}
}
]
}
}
}
Listing conversations
query Conversations($input: GuidedSellingConversationSearchInput) {
guidedSellingConversations(input: $input) {
itemsFound
items {
id
version
language
turnCount
completed
createdAt
}
}
}
Variables:
{
"input": {
"flowId": "01a10f3c-5b7e-7d42-9a61-3c8e2f4b7d90",
"offset": 2,
"sortInputs": [{ "field": "LAST_MODIFIED_AT", "order": "DESC" }]
}
}
Expected response:
{
"data": {
"guidedSellingConversations": {
"itemsFound": 412,
"items": [
{
"id": "3f6c1a52-8e0b-4d7a-9c2e-5b8f0d4a7e19",
"version": 1,
"language": "EN",
"turnCount": 3,
"completed": true,
"createdAt": "2026-10-06T13:20:31.000Z"
},
{
"id": "b0d9e7a4-1c62-4f35-8e1d-7a2c9f6b3e58",
"version": 1,
"language": "NL",
"turnCount": 2,
"completed": false,
"createdAt": "2026-10-06T13:12:07.000Z"
}
]
}
}
}
Without sortInputs, the conversations with the latest step come first. id is the conversationId the storefront sent. turnCount is the number of steps recorded, the opening question included. completed is true once the conversation reached the advice.
Filter with flowId, ids, createdAt and lastModifiedAt, sort on CREATED_AT, LAST_MODIFIED_AT or TURN_COUNT, and page through the results with page and offset. A list can also select turns and outcomes of each conversation: guided selling reads them for the whole page at once.
A conversation records at most 100 steps. A step that repeats the one before it, such as a page reload, is served but not recorded again.
Reading a conversation
guidedSellingConversation returns one conversation with its steps, a page at a time, and every outcome:
query Conversation($id: ID!, $turns: GuidedSellingConversationTurnSearchInput) {
guidedSellingConversation(id: $id) {
id
version
language
completed
turns(input: $turns) {
itemsFound
page
pages
items {
index
cacheClass
answers {
question
answer
typed
}
question {
question
}
advice {
headline
items {
productId
clusterId
reason
}
}
error {
code
reason
}
modelCalls {
id
speculative
model
effort
outcome
inputTokens
outputTokens
cacheReadInputTokens
latencyMs
}
}
}
outcomes {
event
productId
quantity
createdAt
}
}
}
Variables:
{
"id": "3f6c1a52-8e0b-4d7a-9c2e-5b8f0d4a7e19",
"turns": { "page": 1, "offset": 12 }
}
Expected response:
{
"data": {
"guidedSellingConversation": {
"id": "3f6c1a52-8e0b-4d7a-9c2e-5b8f0d4a7e19",
"version": 1,
"language": "EN",
"completed": true,
"turns": {
"itemsFound": 3,
"page": 1,
"pages": 1,
"items": [
{
"index": 1,
"cacheClass": "STATIC",
"answers": [],
"question": { "question": "Where will the printer be used?" },
"advice": null,
"error": null,
"modelCalls": []
},
{
"index": 2,
"cacheClass": "HIT",
"answers": [
{ "question": "Where will the printer be used?", "answer": "In a warehouse or on the production floor", "typed": false }
],
"question": { "question": "How many labels do you print on a busy day?" },
"advice": null,
"error": null,
"modelCalls": [
{
"id": "01a10f41-7c2e-7b19-8d4a-2f6e9c1b5a37",
"speculative": true,
"model": "claude-sonnet-5-5",
"effort": "MEDIUM",
"outcome": "QUESTION",
"inputTokens": 402,
"outputTokens": 913,
"cacheReadInputTokens": 3874,
"latencyMs": 6120
}
]
},
{
"index": 3,
"cacheClass": "COLD",
"answers": [
{ "question": "Where will the printer be used?", "answer": "In a warehouse or on the production floor", "typed": false },
{ "question": "How many labels do you print on a busy day?", "answer": "About 8,000 a day, mostly 6-inch pallet labels", "typed": true }
],
"question": null,
"advice": {
"headline": "An industrial 6-inch printer for your daily pallet labels",
"items": [
{
"productId": 18241,
"clusterId": null,
"reason": "It prints up to 10,000 labels a day on labels up to 6 inch wide, so it handles your 8,000 pallet labels a day."
}
]
},
"error": null,
"modelCalls": [
{
"id": "01a10f52-3b8d-7e64-9a1c-5d7f2e8b4c90",
"speculative": false,
"model": "claude-sonnet-5-5",
"effort": "MEDIUM",
"outcome": "ADVICE",
"inputTokens": 455,
"outputTokens": 1288,
"cacheReadInputTokens": 3874,
"latencyMs": 8740
}
]
}
]
},
"outcomes": [
{ "event": "CONVERTED", "productId": 18241, "quantity": 1, "createdAt": "2026-10-06T13:21:52.000Z" }
]
}
}
}
turns holds 12 steps per page unless you set offset, in the order they happened.
Each turn holds the answers given before it and the question, the advice or the error that the customer got. cacheClass tells how the step was produced, which is what decided how long the customer waited:
cacheClass | How the step was produced |
|---|---|
STATIC | The opening question, from the settings. No model call. |
HIT | A stored step, usually one prepared in advance |
INFLIGHT | A step that was already being prepared for the same answers when the customer asked for it |
COLD | Written by the model for this request, while the customer waited |
modelCalls lists the model calls that produced the step the customer got. For a COLD or INFLIGHT step, those are the calls made for it. For a HIT step, they are the calls that produced the stored step, made in advance or for another conversation: serving it cost nothing. The opening question has none. speculative is true for calls made in advance, when nobody was waiting. outcome is one of:
outcome | Meaning |
|---|---|
QUESTION | A valid next question |
ADVICE | A valid advice |
REJECTED | A step that failed the check, for example a product id that is not in the catalog. Guided selling tries once more. |
ERROR | The call to the model failed or timed out |
Improving a flow with the history
- Typed answers (
typed: true) show what customers want to say that the options do not cover. Turn answers that come back often into a rule in the instruction or an option of the opening question. - Steps with an error show what customers ran into.
error.codeis the code the storefront received anderror.reasonsays why, for example the model vendor's own words for a refused key or the problems of a step that failed the check twice. - Conversations that do not complete show where customers stop.
- Model calls show what the flow cost. A call shows under every step it served, in every conversation that got that step, so count each call once, by its
id.inputTokensandoutputTokensare billed at the vendor's full rate,cacheReadInputTokensat a fraction of it andcacheCreationInputTokensat a little more than the full rate. - Versions can be compared with
guidedSellingFlowStats, filtered byversion.
Personal data
What customers type can contain personal data. Guided selling keeps recorded conversations for a year and then deletes them, with what the customers typed and the outcomes reported for them. Deleting a conversation or its flow deletes it earlier. Only keys and users with Owner access on the Configuration role can read conversations. The statistics contain no text from conversations, but the conversations they count go after a year as well.
To erase one conversation, for example when a customer asks you to, delete it by its conversationId:
mutation DeleteConversation($id: ID!) {
guidedSellingConversationDelete(id: $id)
}
It deletes the conversation's steps, including what the customer typed, together with the outcomes reported for it. The statistics no longer count it. It needs Owner access on the Configuration role. An unknown id returns GUIDED_SELLING_CONVERSATION_NOT_FOUND_ERROR.
The conversationId and the outcome reports carry no customer identity, so a recorded conversation is not linked to a customer account. Make sure your storefront does not put personal data in the conversationId.