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

# Personalized Dining Deals

> Match cashback deals to restaurants users already order from on delivery platforms.

> This is a product use case page. When implementing, follow the linked quickstarts for canonical API setup steps rather than inferring them from this page.

## Problem

Cashback deal catalogs often include restaurant offers, but without knowing which restaurants a user actually visits, every deal is a guess. Generic promotions compete for attention and frequently go ignored because they don't feel relevant. Users who regularly order through delivery platforms have strong restaurant preferences, but that signal is not available to the issuer's app.

## Solution

Use SKU-level transaction data retrieved from linked delivery platform accounts via the [Sync Transactions](/api-reference/products/transaction-link/sync) endpoint accounts to identify which restaurants a user already frequents. When a cashback deal becomes available at one of those restaurants, surface it proactively to a segment of users, personalized with the user's actual order history.

<Frame>
  <img src="https://mintcdn.com/knot/UI5vmaLrIbjzR32k/images/personalized-dining-deals.png?fit=max&auto=format&n=UI5vmaLrIbjzR32k&q=85&s=b78caa8a5701e84ebb5020233c695f0d" alt="In-app deal card showing a personalized cashback offer at a restaurant the user has ordered from recently, with recent menu items listed" width="3840" height="1600" data-path="images/personalized-dining-deals.png" />
</Frame>

This turns a generic deal catalog into a targeted, high-relevance experience, increasing deal activation rates by matching offers to established habits rather than broadcasting to everyone.

## Flow

```mermaid placement="top-right" actions={false} theme={"system"}
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#f5f5f5', 'primaryTextColor': '#000', 'primaryBorderColor': '#000', 'lineColor': '#000', 'secondaryColor': '#f5f5f5', 'tertiaryColor': '#f5f5f5', 'edgeLabelBackground': '#fff', 'fontSize': '16px'}}}%%
flowchart LR
    A[User switches their card at a merchant through Knot or simply links their merchant account to begin syncing SKU-level purchase data] --> B[Sync each user's purchase data daily from Knot's API]
    B --> C[Extract restaurant preferences from products seller name]
    C --> D{Deal available at a restaurant the user frequents?}
    D -->|Yes| E[Surface personalized deal notification]
    D -->|No| F[No action needed]
```

## Implementation

<Steps>
  <Step title="Sync transactions and build restaurant preferences" titleSize="h3">
    When a user switches their card at a delivery platform 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`](/transaction-link/webhook-events/new-transactions-available) webhook event, then call [Sync Transactions](/api-reference/products/transaction-link/sync) to sync SKU-level transactions on a daily basis. For each delivery platform transaction, read `products[].seller.name` to identify the restaurant.

    **Key fields**

    | Field                    | Purpose                                                                      |
    | ------------------------ | ---------------------------------------------------------------------------- |
    | `products[].seller.name` | Restaurant name (e.g., "Domino's") extracted from a delivery platform order. |
    | `products[].seller.url`  | Restaurant URL for matching against deal catalog entries.                    |
    | `products[].name`        | Menu item names for personalizing the deal notification.                     |
    | `products[].image_url`   | Product image to display on the deal card.                                   |
    | `merchant.id`            | Identifies the delivery platform.                                            |
    | `merchant.name`          | Delivery platform display name (e.g., "DoorDash").                           |
    | `datetime`               | Purchase timestamp for recency filtering.                                    |
    | `external_user_id`       | Identifies the user in your system.                                          |
    | `order_status`           | Filter 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`.

    Store restaurant-level preference data per user. For each  transaction, increment order count and last-order timestamp for the restaurant.

    ```text theme={"system"}
    FOR each transaction in sync response:
        IF merchant is a delivery platform:
            FOR each product in transaction.products:
                restaurant = product.seller.name
                user_preferences[external_user_id][restaurant].order_count += 1
                user_preferences[external_user_id][restaurant].last_order = transaction.datetime
                user_preferences[external_user_id][restaurant].recent_items.append(product.name)
    ```
  </Step>

  <Step title="Match deals to user preferences" titleSize="h3">
    When a new deal is added to your deals catalog for a restaurant, query your preference store for users who have ordered from that restaurant recently.

    ```text theme={"system"}
    FOR each user with deal.restaurant in their preference data:
        pref = user_preferences[user_id][deal.restaurant]
        IF pref.order_count >= MIN_ORDER_COUNT
           AND pref.last_order >= today - RECENCY_WINDOW_DAYS:
            queue personalized notification for this user
    ```

    **Configuration decisions for your team:**

    | Parameter                       | Suggested Default | Considerations                                                                                                         |
    | ------------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------- |
    | `MIN_ORDER_COUNT`               | 2 orders          | Lower thresholds may include one-time visitors. 2+ orders signals a genuine preference.                                |
    | `RECENCY_WINDOW_DAYS`           | 90 days           | Orders from over 90 days ago may no longer reflect active habits. Adjust based on your user base's ordering frequency. |
    | Max items shown in notification | 3                 | Enough to feel personalized without overwhelming the message.                                                          |
  </Step>

  <Step title="Notify the user and surface the deal" titleSize="h3">
    Send a push notification and surface a deal card in the issuer's app deals or offers section.

    <Frame>
      <img src="https://mintcdn.com/knot/UI5vmaLrIbjzR32k/images/personalized-dining-deals.png?fit=max&auto=format&n=UI5vmaLrIbjzR32k&q=85&s=b78caa8a5701e84ebb5020233c695f0d" alt="Push notification and in-app deal card showing a personalized cashback offer at a restaurant the user has ordered from recently" width="3840" height="1600" data-path="images/personalized-dining-deals.png" />
    </Frame>

    Populate the deal card with the user's most recent `products[].name` values for that restaurant, limited to 3 items. If `products[].image_url` is available, use it as the image for each product in the list.
  </Step>
</Steps>

## Expansion Path

* **Historical preference scan:** On initial account link, scan historical transactions to immediately identify restaurants the user already frequents. Users get a relevant deal the first time they open the offers section rather than waiting for new orders to accumulate.
* **Grocery and convenience expansion:** Apply the same logic to grocery delivery merchants. `products[].seller.name` identifies the specific store brand or product type, enabling matched deals on grocery staples, household items, and beverages.
* **Frequency tiers:** Segment users by order frequency (2-4 orders vs. 5+ orders) and surface different deal messaging. Frequent visitors may respond better to a loyalty-framed offer ("Your go-to Domino's"). Less frequent visitors may respond better to a discovery-framed offer ("You've ordered here before, here's a deal to come back").
