Skip to main content
Click “Copy Page” to copy this use case as markdown.

Problem

Most people buy the same grocery and household products week after week, but every trip to the store starts from scratch: trying to remember what’s running low, writing items down in a notes app, or showing up and improvising. With access to SKU-level transaction data, an app can identify exactly which products a user buys repeatedly and turn that into something useful.

Solution

Use SKU-level transaction data from Knot’s Sync Transactions endpoint to identify products a user buys repeatedly at linked grocery and retail accounts, then generate a personalized shopping list pre-populated with those items.
Banking app screen showing a personalized shopping list with frequently purchased grocery items, checkboxes, and an estimated total
This turns purchase history into a practical, recurring utility that gives users a reason to open the issuer’s app before every shopping trip.

Flow

Implementation

1

Sync transactions and build a purchase history

When a user switches their card at a merchant or they simply link their merchant account w/o switching their card, Knot begins collecting transaction data for that account. Listen for the NEW_TRANSACTIONS_AVAILABLE webhook event, then call Sync Transactions to sync SKU-level transactions on a daily basis. For each transaction, iterate over the products array and update a per-user, per-merchant purchase index.Key fields
FieldPurpose
products[].external_idUnique product identifier for deduplication across orders.
products[].nameProduct display name for the shopping list.
products[].price.unit_priceMost recent unit price, used to estimate the list total.
products[].image_urlProduct image for the list UI.
products[].urlLink to the product page for the list UI.
merchant.idIdentifies the retailer. Scope the list per merchant.
merchant.nameRetailer display name.
datetimePurchase timestamp for recency scoring.
external_user_idIdentifies the user in your system.
order_statusFilter to completed orders only.
Only include transactions with order_status of COMPLETED, DELIVERED, PICKED_UP, SHIPPED, BILLED, or ORDERED. Filter out CANCELLED, REFUNDED, and FAILED.
FOR each transaction in sync response:
    FOR each product in transaction.products:
        key = (external_user_id, merchant.id, product.external_id)
        purchase_index[key].count += 1
        purchase_index[key].last_purchased = transaction.datetime
        purchase_index[key].name = product.name
        purchase_index[key].last_price = product.price.unit_price
        purchase_index[key].image_url = product.image_url
        purchase_index[key].url = product.url
2

Generate the shopping list

When a user’s purchase index reaches the minimum threshold, compile their shopping list. Run this on initial sync (to catch historical data) and refresh after each new transaction batch.
candidates = products in purchase_index[user][merchant]
    WHERE count >= MIN_PURCHASE_COUNT
    AND last_purchased >= (today - PURCHASE_WINDOW_DAYS)

ranked = sort candidates by count descending, then last_purchased descending

shopping_list = ranked[:MAX_LIST_SIZE]
estimated_total = sum(p.last_price for p in shopping_list)
Configuration decisions for your team:
ParameterSuggested DefaultConsiderations
MIN_PURCHASE_COUNT3 purchases2 purchases may include one-time buys. 3+ is a reliable signal of a regular item.
PURCHASE_WINDOW_DAYS30 daysOnly count purchases within this window. Avoids surfacing products bought 3 times over a year that are not part of a regular routine.
MAX_LIST_SIZE30 itemsCovers a typical weekly grocery run without feeling overwhelming.
List refresh frequencyAfter each new transaction syncKeeps the list current as buying habits change.
3

Surface shopping list in the app

Send a push notification when the list is first generated or materially updated, and surface it as a persistent in-app feature.
Banking app screen showing a personalized shopping list with frequently purchased grocery items, checkboxes, and an estimated total
Users should be able to check off items as they shop, add one-off items manually, and skip items they don’t need that week.

Expansion Path

  • Predictive reorder timing: For each recurring item, track the average interval between purchases (e.g., milk every 6 days). Surface items on the list when they are likely running low, rather than showing all items at once every week.
  • Cross-merchant list: Combine repeat-purchase data across multiple linked merchants into one unified list. For items that appear at more than one merchant, surface the lower price as a recommendation.
  • Store-brand swap suggestions: For each name-brand item on the list, check whether a comparable store-brand product is available at a lower price and offer an inline swap. This reuses the same purchase history data and adds a savings angle without requiring a separate flow.