---
title: "What a Cart Abandonment Model Actually Sees"
description: "A storefront emits a huge volume of behavioral data. Here's why pattern recognition beats a fixed rule — and what we deliberately don't collect."
canonical: https://navona.ai/blog/what-a-cart-abandonment-model-actually-sees
generator: scripts/generate-agent-md.mjs
published: 2026-08-26
category: product
tags: ["machine learning","cart abandonment","privacy"]
---

# What a Cart Abandonment Model Actually Sees

We don't publish the exact signals or thresholds our model uses to
decide when to intervene — that's on purpose, for the same reason a
spam filter doesn't publish its exact rules. But we can talk honestly
about the shape of the problem, and about what the model is built on.

## A storefront produces more data than a single rule can use

Every session on a Shopify storefront running Navona generates a
stream of client-side and web-pixel events — page views, product
interactions, cart changes, navigation patterns, and more — each
carrying a number of fields describing the moment it happened.
Multiply that across a session, and a single shopper's visit isn't one
data point. It's a sequence of many, each with its own context.

A fixed-rule script can only look at a handful of those signals at a
time, combined with hand-picked thresholds: if this happens, and this
hasn't happened, and it's been this long, trigger. That's a reasonable
way to build a first version, and it works. But it has a ceiling. The
rule doesn't get better with more traffic — it does the same thing on
day one and on day one thousand, and every edge case it misses has to
be found by a human and hand-coded in as a new branch.

## Pattern recognition over the whole surface is a different tool

A model trained across that same event surface isn't limited to a
handful of hand-picked signals evaluated one at a time. It can weigh
many fields against each other simultaneously, and its read on what a
given pattern means improves as more sessions accumulate. Where a
fixed rule plateaus the day it ships, a model has a mechanism to keep
improving — that's the actual argument for building one, independent
of any specific signal it happens to weigh today.

We're deliberately not going to describe which signals matter most or
how they're combined. That's true of the fixed-rule approach too, for
the same reason: publishing the exact conditions that trigger an
intervention would let anyone reverse-engineer around them, which
defeats the point of having them at all.

## The same behavior means different things on different stores

A pause in the middle of a session is not the same signal on a
€30 impulse-purchase store as it is on a €300 considered-purchase
store. On the cheaper store it might already indicate real hesitation;
on the pricier one, the same pause might be completely normal
deliberation while a shopper compares options. A single fixed
threshold applied uniformly across stores gets this wrong in one
direction or the other on any store that isn't close to average. A
model that learns store-specific patterns, rather than applying one
global rule everywhere, is built to account for exactly this kind of
variance — store to store, and category to category within a store.

This is also why a signal ranking wouldn't be an honest thing to
publish even if we wanted to: "signal X matters most" is only ever
true in aggregate, and the entire point of the model is that it
doesn't apply the same weighting everywhere.

## What the model doesn't need

The strongest trust signal here isn't about what we collect — it's
about what we don't. The intervention doesn't require an email address
or a phone number to work. It reads and reacts to on-page shopping
behavior in the moment, which means we're not asking a shopper to hand
over contact information before we can do the job. If a tool you're
comparing wants an email address to power its logic, that's a design
choice, not a technical necessity — behavioral intervention doesn't
need it.

## What we'll say, and what we won't

We'll talk about the shape of the data, the reasoning for using a
model instead of a fixed rule, and why one signal can't be ranked as
universally more important than another. We won't publish the
specific signals, the thresholds, or the timing our model uses to
decide when to act. That's the same instinct behind being explicit
that our own attribution numbers are attribution, not lift — see
[Attribution Is Not the Same as Lift](https://navona.ai/blog/attribution-vs-measured-lift).

## Appendix: the event catalog, in full

"A large surface" is a claim that should be checkable. Here is every
event type NavonaAI's storefront integration produces, current as of
26 Aug 2026. One field is deliberately incomplete, and we say exactly
which one and why, rather than pretend the appendix is unabridged.

### Storefront events (Shopify's own web-pixel taxonomy)

These are Shopify's standard pixel event types — not proprietary to
Navona, and the same events any pixel-based analytics tool on the
platform receives. Every event carries a common envelope
(`id`, `name`, `timestamp`, `clientId`) plus an event-specific payload.

| Event | Payload |
|---|---|
| `product_added_to_cart` | Shopify's standard cart-line payload, forwarded unmodified |
| `product_removed_from_cart` | Shopify's standard cart-line payload, forwarded unmodified |
| `product_viewed` | Shopify's standard product payload, forwarded unmodified |
| `collection_viewed` | `collection.id`, `collection.title` |
| `search_submitted` | `searchResult.query`, matched product/variant IDs |
| `checkout_started` | `buyerAcceptsEmailMarketing`, `buyerAcceptsSmsMarketing`, `attributes`, `token`, `currencyCode`, `discountApplications`, `discountsAmount`, `email`, `phone`, `lineItems` (variant ID + discount allocations), `order`, `delivery` |
| `checkout_completed` | Same shape as `checkout_started` |
| `checkout_contact_info_submitted` | none — fires with no payload |
| `checkout_address_info_submitted` | none — fires with no payload |
| `checkout_shipping_info_submitted` | none — fires with no payload |
| `payment_info_submitted` | none — fires with no payload |
| `cart_viewed` | none — fires with an empty payload |
| `page_viewed` | none — fires with no payload |
| `alert_displayed` | Shopify's standard alert payload, forwarded unmodified |
| `ui_extension_errored` | the error object |

`email` and `phone` above are Shopify's own standard checkout fields,
present because a checkout inherently has them once a shopper reaches
that step — not something we ask for. The intervention itself, covered
above, never requires either.

### Navona's own prevention events

Session- and outcome-level events our own script emits, independent
of the pixel above. Every one carries `storeId`, `sessionId`,
`clientId`, `cartId`, and an optional `occurredAt`.

| Event | What it marks |
|---|---|
| `session_started`, `cart_created` | session and cart lifecycle |
| `popup_shown`, `popup_reshown` | the offer rendered |
| `popup_accepted`, `popup_rejected` | the shopper's response |
| `popup_copy_failed`, `popup_delivery_failed` | reliability telemetry — the offer didn't reach the shopper cleanly |
| `chatbot_accepted`, `chatbot_rejected`, `objection_accepted`, `objection_rejected`, `user_engaged`, `user_messaged` | the objection-handling conversation, where offered |
| `new_abandoning`, `repeat_abandoning`, `abandonment_detected` | abandonment classification, first-time vs. repeat |

`popup_shown` and `popup_accepted` also carry a `discountCode` and a
`trigger` field. **We're not publishing the `trigger` field's values
here** — they're the specific behavioral classification a signal-level
ranking post would have exposed, which is the same thing this post
already said we wouldn't do. A small number of additional internal
telemetry events exist and aren't individually listed, for the same
reason.

[See it on your own store](https://navona.ai/pricing)

## FAQ

### What data does a cart abandonment model actually use?

It draws on the client-side and web-pixel events a storefront already generates during a session — page views, product and cart interactions, and navigation behavior — each carrying multiple fields of context. We don't publish which specific signals the model weighs most heavily.

### Why use a model instead of a fixed rule for detecting abandonment?

A fixed rule evaluates a small, hand-picked set of conditions and performs the same way indefinitely. A model can weigh many signals against each other at once and improve as more session data accumulates, which a fixed rule structurally cannot do.

### Does the same shopper behavior mean the same thing on every store?

No. A pause that signals real intent to leave on a low-priced, impulse-purchase store can be completely normal deliberation on a higher-priced, considered-purchase store. That variance is part of why a single global threshold doesn't generalize well across stores.

### Does NavonaAI need a shopper's email or phone number to work?

No. The intervention responds to on-page shopping behavior in the moment, so it doesn't require capturing an email address or phone number before it can act — unlike tools that depend on contact details to function.

### Will NavonaAI publish exactly which signals trigger an intervention?

No, deliberately. Publishing the exact signals, thresholds, or timing would let anyone reverse-engineer around them, which defeats the purpose of having them. This is consistent with how most tools in this category protect their mechanism.
