Where exactly do shoppers drop off in checkout?

Build the product-view to purchase funnel with drop-off and time-on-step. The 1-prompt ecommerce funnel that Shopify analytics doesn't ship.

Published

difficulty beginner · time to value 2 minutes

Start from this

Build the cart-abandonment funnel: product_view → add_to_cart → checkout_started → purchase. Show drop-off and average time-on-step for the last 30 days.

Why this matters

Most ecommerce shops live in Shopify Analytics or GA4. Both can show you “conversion rate” but neither tells you exactly which step is bleeding. Shopify’s funnel is product-detail to purchase as a single hop. GA4 needs 30 minutes of custom event configuration per funnel. The result: nobody runs the funnel, nobody sees the leak.

The leak is almost always one of three steps:

  1. Add-to-cart → checkout-started: “shipping cost shown” surprise → cart abandonment
  2. Checkout-started → purchase: payment friction (declined card, slow Stripe response)
  3. Product-view → add-to-cart: product page conversion (price, photos, reviews)

You don’t know which until you cut the funnel. Agentry proves the approved event names and properties first, then runs the funnel with HogQL or a query blueprint. A dashboard or public URL is optional output when you explicitly ask for it.

What you get

  • A 4-step funnel with absolute counts and conversion % at each step
  • Average time-on-step (where shoppers are hesitating)
  • Optional browser-safe output when you explicitly ask for a persistent view

Walk through it

You

Build the cart-abandonment funnel: product_view → add_to_cart → checkout_started → purchase. Show drop-off and time-on-step for the last 30 days.

Agent

Let me check your event vocabulary first.

Endpoint: GET /v1/projects/:project_id/event-names
Exact shape: /v1/openapi.json?path=%2Fv1%2Fprojects%2F%7Bproject_id%7D%2Fevent-names&method=get
Use query parameters, not a JSON body.
Query/filter concept:
  matching: "view|cart|checkout|purchase|order"
{
  "events": [
    { "name": "product_viewed",    "count": 142000 },
    { "name": "add_to_cart",       "count":  21400 },
    { "name": "checkout_started",  "count":   8800 },
    { "name": "order_completed",   "count":   4200 }
  ]
}
Agent

Your event names are slightly different — product_viewed (not product_view), order_completed (not purchase). Adjusting and running the funnel.

Endpoint: POST /v1/projects/:project_id/query-blueprints/:blueprint_id/run
Exact shape: /v1/openapi.json?path=%2Fv1%2Fprojects%2F%7Bproject_id%7D%2Fquery-blueprints%2F%7Bblueprint_id%7D%2Frun&method=post
Blueprint: funnel_3_step
Fetch GET /v1/query-blueprints/funnel_3_step for the allowed params before running it.
Concept fields:
  params: {
    step1: "add_to_cart",
    step2: "checkout_started",
    step3: "order_completed",
    days: 30
  }
{
  "steps": [
    { "name": "product_viewed",    "count": 142000, "conversion": 1.000, "avg_time_to_next_s": 94 },
    { "name": "add_to_cart",       "count":  21400, "conversion": 0.151, "avg_time_to_next_s": 142 },
    { "name": "checkout_started",  "count":   8800, "conversion": 0.411, "avg_time_to_next_s": 380 },
    { "name": "order_completed",   "count":   4200, "conversion": 0.477 }
  ],
  "overall": 4200 / 142000  // 2.96%
}
Agent

Funnel built. The numbers tell a clear story:

  • Product view → Add to cart: 15.1% (typical: 8-15% for non-DTC, 10-25% for DTC. You’re upper-mid — fine)
  • Add to cart → Checkout started: 41.1% (typical: 40-60%. Slightly low. People put things in cart and bail)
  • Checkout started → Purchase: 47.7%THE LEAK (typical: 60-80%. You’re losing ~13k orders/month here)
  • Overall: 2.96% (industry baseline ~2-3%, you’re average)

The 47.7% checkout-to-purchase is the actionable number. People literally start checking out and bail. Most common cause: shipping surprise, slow Stripe page, or no Apple Pay / payment options. The 380-second avg time-on-checkout-started is suspicious — they’re sitting there for 6+ minutes thinking.

I can publish this only if you want a browser-safe view and the approved funnel can be represented by a query blueprint. Otherwise I’ll keep the answer server-side and give you the exact follow-up flow to trigger.

Endpoint: POST /v1/projects/:project_id/public-queries
Exact shape: /v1/openapi.json?path=%2Fv1%2Fprojects%2F%7Bproject_id%7D%2Fpublic-queries&method=post
Blueprint: funnel_3_step
Publish only real query-blueprint results; use Agentry's returned `public_url`.
Concept fields:
  blueprint_id: "funnel_3_step",
  description: "Cart Abandonment Funnel (30d)",
  params: {
    step1: "add_to_cart",
    step2: "checkout_started",
    step3: "order_completed",
    days: 30
  }
{ "id": "<publication_id>", "public_url": "https://api.agentry.sh/v1/public/q/<publication_id>" }

The output

Cart Abandonment Funnel (30d)

product_viewed            142,000  ──────────────  100%
   ↓  94s avg              21,400  ▎  15.1%   (industry typical: 8-15%) ✓
add_to_cart                21,400  ▎  15.1%
   ↓  142s avg              8,800  ▎   6.2%   (industry typical: 6-10%) ✓
checkout_started            8,800  ▎   6.2%
   ↓  380s avg              4,200  ▎   3.0%   (industry typical: 4-5%) ✗
order_completed             4,200  ▎   3.0%

Headline: 53% drop at checkout (4,600 abandoned orders/month) ★

Likely causes:
  - Slow checkout page load (380s avg time suggests session timing out)
  - Surprise shipping cost only shown at checkout
  - No Apple Pay / Google Pay / Stripe Link
  - Required account creation (vs guest checkout)

Public view:
  Use Agentry's returned public_url after publishing a real query blueprint.

Suggested next investigations:
  - stripe-payment-failure: are declines causing the bail-out?
  - checkout-completion-time: split p99 by device (mobile is usually 8x worse)

Setting it up

You need 4 events with stable distinct_id per shopper. For guest checkout, use a visitor id from a first-party cookie:

// Get or create visitor id (cookie/localStorage)
function getVisitorId(): string {
  let id = localStorage.getItem("visitor_id");
  if (!id) {
    id = crypto.randomUUID();
    localStorage.setItem("visitor_id", id);
  }
  return id;
}

const distinct_id = currentUser?.email ?? getVisitorId();

// Fire on each step
async function track(event: string, properties: Record<string, unknown> = {}) {
  await fetch(`https://api.agentry.sh/v1/analytics/`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.AGENTRY_PUBLIC_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ event, distinct_id, properties }),
  });
}

// Product page
track("product_viewed", { sku: p.sku, price: p.price, category: p.category });

// Add to cart
track("add_to_cart", { sku: p.sku, qty, cart_total: cart.total });

// Begin checkout
track("checkout_started", { cart_value: cart.total, item_count: cart.items.length });

// Confirmation page
track("order_completed", { order_id: order.id, total: order.total, items: order.items.length });

If you’re on Shopify, the events fire by default with Shopify Analytics — you can swap the destination to Agentry by adding a Web Pixel script that pipes events to the Agentry analytics endpoint.

Variations

  • “Same funnel but only for mobile traffic. The drop-off is usually 2-3x worse on mobile.”
  • “Cart abandonment by SKU — are certain products driving the bail-outs?”
  • “What’s the average cart value of abandoned vs completed orders? Are big carts more likely to bail?”
  • “Weekly cron: post the previous week’s funnel snapshot to #shop-ops every Monday morning.”

Adapt this playbook in your own agent.

Ask your agent to map the starter prompt to your saved signal map, live events, and the current HTTP API before answering.

Set up Agentry in this repo by following https://agentry.sh/install.md. I authorize you to: run its device-code login and save the key to ~/.agentry/credentials.json, read this repo, propose an instrumentation plan for my approval, and edit code after I approve it.

+ Full access
5.5 Extra High
  1. 1. Open your repo in Codex, Claude Code, Cursor etc.
  2. 2. Paste the install prompt.
  3. 3. Your agent reads the install doc and shows you an implementation plan for approval.