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

# Using API responses

The Frenzy storefront script exposes `frenzAfterApiCallBack`, a global callback that gives your theme or custom JavaScript access to the complete Frenzy response after the built-in interface has rendered it. Use it when you need to extend Frenzy with your own analytics, UI, experiments, or integrations without replacing the standard search and recommendation experience.

## Quick start

Define the callback on `window` before `frenzy-search.js` loads. The name is case-sensitive and intentionally spelled `frenzAfterApiCallBack`.

```js theme={null}
window.frenzAfterApiCallBack = function (response) {
  console.log('Complete Frenzy response:', response);

  const results = response?.results?.results ?? [];
  const requestId = response?.results?.request_id;
  const assignmentDate = response?.ab_test_assignment_date;

  // Add your own non-blocking logic here.
};
```

Frenzy checks whether this global is a function and invokes it with the response object. The callback is not awaited and its return value is not used, so it should finish quickly and should not be used to change Frenzy's response before Frenzy renders it.

## When the callback runs

The callback runs after Frenzy has processed and rendered a supported API response. Depending on the components enabled on the storefront, this includes search results, collection results, autocomplete suggestions, recommendation widgets, and bundles.

It can run more than once in one shopper session. For example, expect another invocation when the shopper changes a filter or sort order, moves between result pages, loads additional products through infinite scroll, performs another search, or opens suggestions. Build the callback as an event handler, not as a one-time page-load hook.

## Working with the response

The callback receives the response payload used by the active Frenzy feature. Its exact shape depends on that feature and its configuration, so use optional chaining and defaults rather than assuming every field is present.

```js theme={null}
window.frenzAfterApiCallBack = function (response) {
  const search = response?.results;

  const products = search?.results ?? [];
  const productCount = search?.products_found ?? 0;
  const pageCount = search?.page_count ?? 0;
  const requestId = search?.request_id ?? null;

  const selectedFilters = search?.filters ?? {};
  const availableFacets = search?.facet_fields ?? {};
  const correctedQuery = search?.corrected_query ?? null;

  console.log({ products, productCount, pageCount, requestId });
};
```

For search and collection experiences, the following fields are commonly useful:

* `response.results.results` — the returned product records. Each record contains the product data configured for the Frenzy experience, such as identifiers, SKU, product name, price, images, options, custom data, and other storefront attributes where available.
* `response.results.request_id` — identifies the Frenzy result request. Preserve it when you need to associate a shopper interaction or downstream event with the result set that produced it.
* `response.results.products_found` and `response.results.page_count` — total matched products and available pages, useful for a custom result-count indicator or pagination integration.
* `response.results.filters` and `response.results.facet_fields` — current filter values and available facets. These are useful when mirroring filter state in a custom component.
* `response.results.corrected_query` — the query correction when Frenzy has applied one.
* `response.global_setting`, page settings, CSS settings, filter order, and labels — configuration used by the current Frenzy component. These fields are feature-dependent.

Recommendation and bundle responses have a different schema. Inspect `response` in your browser's developer tools for the specific component you are extending, then feature-detect the properties you use. Do not rely on a field being available in every callback invocation.

## A/B test assignment date

`response.ab_test_assignment_date` tells you when the shopper was assigned to the current Frenzy A/B-test experience. It represents the assignment time, not the time that the current API response was generated.

This field is useful for keeping external analytics and experiment tooling aligned with Frenzy. For example, you can send it with a product-impression or conversion event so analysts can distinguish a shopper's original experiment assignment from later search activity.

```js theme={null}
window.frenzAfterApiCallBack = function (response) {
  const requestId = response?.results?.request_id;
  const assignmentDate = response?.ab_test_assignment_date ?? null;

  if (!requestId) return;

  window.dataLayer?.push({
    event: 'frenzy_results_rendered',
    frenzy_request_id: requestId,
    frenzy_ab_test_assignment_date: assignmentDate,
    frenzy_products_found: response?.results?.products_found ?? 0
  });
};
```

Keep the assignment date as the value returned by Frenzy. Do not substitute the browser's current timestamp: doing so would record the render time rather than the actual A/B-test assignment time.

## Avoid duplicate events

Because the callback can be invoked repeatedly, use the request ID to prevent duplicate analytics events for the same response. The example below deduplicates only requests that provide an ID.

```js theme={null}
const seenFrenzyRequests = new Set();

window.frenzAfterApiCallBack = function (response) {
  const requestId = response?.results?.request_id;
  if (!requestId || seenFrenzyRequests.has(requestId)) return;

  seenFrenzyRequests.add(requestId);

  window.dataLayer?.push({
    event: 'frenzy_response_received',
    frenzy_request_id: requestId,
    frenzy_ab_test_assignment_date:
      response?.ab_test_assignment_date ?? null,
    product_count: response?.results?.products_found ?? 0
  });
};
```

## Recommended practices

* Define the callback before Frenzy initializes. If it is added after the relevant response has already been processed, it will not run for that earlier response.
* Use optional chaining and fallback values because response fields differ across search, collections, suggestions, recommendations, and bundles.
* Keep the callback fast. Avoid slow synchronous work or blocking network calls that could affect the shopper's experience.
* Use `request_id` and `ab_test_assignment_date` as supplied by Frenzy when reporting analytics or experiment events.
* Do not modify the response object or rely on callback return values to alter Frenzy rendering. Use the callback to read the response and enhance your own UI or integrations.
* Only forward data to third-party analytics tools in accordance with your storefront's consent and privacy requirements.
