> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentcard.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Showing each store as it is searched

> Show the shopper every store Agentcard is searching, and what each one answered, from the first second of the search.

A search for "a men's linen shirt" asks several stores at once. Your chat can show each one the moment Agentcard starts on it, `checking Gap`, and change the line when the store answers: two shirts at Gap, nothing at 1-800-Flowers, Sephora too slow to wait for. The shopper sees work happening before the first product arrives.

Store statuses reach your app once Agentcard turns them on for every company. Until then, `onMerchantStatus` hears no update and the answer's `search` is `null`, so code written from this guide shows no store line and needs no change when they turn on.

## Show each store as its status changes

Pass `onMerchantStatus` to the buy tool. The callback hears a store each time the store's status changes: `searching` when Agentcard starts on it, then the status it ends with.

```ts chat.ts theme={null}
const buy = buyTool({
  agentcard,
  externalUserId: shopper.id,
  onMerchantStatus: (update) => showStoreLine(shopper.id, update.merchant, update.merchantName, update.status), // your code
});
```

An update carries these fields:

| Field | Type | What it holds |
| - | - | - |
| `conversationId` | string | The conversation the search serves. |
| `searchId` | string | This turn's search. A later turn that searches again has a new one. |
| `merchant` | string | The store's id, such as `gap`, or its domain, such as `livlyclothing.com`. |
| `merchantName` | string | The store's name to show the shopper, such as `Gap`. |
| `status` | string | Where the store stands. See the table below. |
| `results` | number | How many products the search found at the store. |
| `confirmed` | number | How many of them had their price and stock read live, or in the last hour. |
| `firstResultMs` | number or null | Milliseconds from the start of the store's search to its first product. |
| `ms` | number | Milliseconds the store's search took, or has taken so far. |

Key your line by `merchant` and replace it on each update: a store can change more than once in a turn, and a store searched twice reads `searching` again.

## Read what each status means

| Status | What it means | What to show |
| - | - | - |
| `searching` | Agentcard is still searching the store. | `checking Gap` |
| `confirmed` | The store's own site answered with products, their price and stock read live in this search. | `2 at Gap` |
| `recently_confirmed` | Products Agentcard already knew, their price and stock read live at the store in the last hour. | `3 at Target` |
| `confirmation_unavailable` | Products found for the store, none of them read live in this search. Their prices are read again at the store's checkout. | `4 at Walmart` |
| `no_results` | The store answered, with nothing for the ask. | `none at 1-800-Flowers` |
| `timed_out` | The search answered without the store, which was still running. | `Sephora is slow right now` |
| `failed` | The store's search failed. | `couldn't reach Amazon` |

A `timed_out` or `failed` store says nothing about whether the store carries the product. Say so to the shopper in your own words, and never as "none at Sephora".

## Read every store in the answer

The answer's `search` holds every store the turn searched, in the order their searches started, with the same fields in snake case. `final` is `true` once no store is still being searched.

```ts chat.ts theme={null}
const result = await turn.answer(input);
for (const store of result.search?.merchants ?? []) showStoreLine(shopper.id, store.merchant, store.merchant_name, store.status);
if (result.search && !result.search.final) showNote(shopper.id, 'still checking a store or two'); // your code
```

`search` is `null` for a turn that searched no store, such as a reply about the cart.

## Follow one store

A chat that searched one store reads that store's line with `searchAt`, which matches the store by its id, its domain, or its name:

```ts store-line.ts theme={null}
import { searchAt, isMerchantStatusAt } from '@agent-cards/commerce-sdk';

const gap = searchAt(result.search ?? null, 'gap.com')?.merchants[0]; // the one line, or undefined when the turn did not search Gap
const onMerchantStatus = (update) => {
  if (isMerchantStatusAt(update, 'gap.com')) showStoreLine(shopper.id, update.merchant, update.merchantName, update.status);
};
```

## Call the API directly

A streamed `POST /buy` sends each change as a `merchant` event. The following events come from a run of "a men's linen shirt", with the milliseconds since the call started:

```text theme={null}
2625  event: merchant  {"merchant":"gap","merchant_name":"Gap","status":"searching","results":0,"confirmed":0,"first_result_ms":null,"ms":5}
2625  event: merchant  {"merchant":"sephora","merchant_name":"Sephora","status":"searching","results":0,"confirmed":0,"first_result_ms":null,"ms":4}
3025  event: merchant  {"merchant":"1800flowers","merchant_name":"1-800-Flowers","status":"no_results","results":0,"confirmed":0,"first_result_ms":null,"ms":402}
3443  event: merchant  {"merchant":"gap","merchant_name":"Gap","status":"confirmed","results":2,"confirmed":2,"first_result_ms":591,"ms":821}
4722  event: merchant  {"merchant":"sephora","merchant_name":"Sephora","status":"timed_out","results":0,"confirmed":0,"first_result_ms":null,"ms":2091}
```

Each event also carries `conversation_id` and `search_id`. The envelope carries the whole list as `search`, with `search_id`, `final`, `elapsed_ms`, `merchants` and `index`. `index` holds how many products Agentcard's own product index answered and how long its read took, or `null` when the turn read none.

## Check it in the sandbox

Once store statuses are on for your company:

1. Send "a men's linen shirt" to your agent as a test shopper.
2. Watch a line appear for each store, `searching` first.
3. See each line change as its store answers, and the answer's `search` list the same stores with `final: true`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.