> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/sdgm/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/sdgm/_mcp/server.

# Personalized Email Recommendations

Choose products to feature in an email for each customer who can receive the campaign. The predictive target is an item the customer may purchase in the next 14 days. Kumo Engine ranks possible purchases; your current customer and catalog data determine which ranked items can appear in the email.

## Data and relationships

This example assumes a prepared Kumo Engine `graph`, a matching `snapshot`, and these tables:

| Table          | Required columns                               | Purpose                                                |
| -------------- | ---------------------------------------------- | ------------------------------------------------------ |
| `users`        | `user_id` as the primary key, `email_opt_in`   | Defines customers and their current email eligibility. |
| `items`        | `item_id` as the primary key, `email_featured` | Defines products approved for this campaign.           |
| `transactions` | `user_id`, `item_id`, `timestamp`              | Records purchases and their times.                     |

Connect `transactions.user_id` to `users.user_id` and `transactions.item_id` to `items.item_id`. Mark `transactions.timestamp` as the time column. The `users` and `items` pandas DataFrames below must reflect the campaign decision time. Their eligibility columns are campaign rules applied after ranking, not predictions made by Kumo Engine.

## Rank purchases for the campaign window

This Python query ranks items each customer may purchase within 14 days after `prediction_time`. `LIST_DISTINCT` makes repeated purchases of one item a single target item in that window. It does not restrict the prediction population to customers who opted in.

```python
from datetime import datetime
from kumo.engine import PredictiveQuery

query_text = (
    "PREDICT LIST_DISTINCT(transactions.item_id, 0, 14, days) "
    "RANK TOP 12 FOR EACH users.user_id"
)
query = PredictiveQuery(graph, query_text)
query.validate()
print(query.get_task_type())  # temporal_link_prediction

prediction_time = datetime(2024, 5, 1)  # UTC in the source extracts.
prediction_table = query.generate_prediction_table(
    snapshot, prediction_time=prediction_time
)
ranked = trainer.predict(
    prediction_table, snapshot=snapshot, num_classes_to_return=12
).frame
```

Here `trainer` is a fitted model for this query. Replace the example time with a UTC campaign decision time after the latest observed purchase. In `ranked`, `ENTITY` identifies a customer, `CLASS` identifies an item, and `SCORE` orders the returned candidates for that customer. The score is not a guaranteed purchase probability.

## Select customers and products for the email

Apply the current email eligibility and campaign catalog rules to the ranked rows. These pandas filters are outside the predictive query. Use the same `user_id` and `item_id` types as the graph tables.

```python
eligible_users = users.loc[users["email_opt_in"].eq(True), ["user_id"]]
featured_items = items.loc[items["email_featured"].eq(True), ["item_id"]]

campaign_candidates = (
    ranked.merge(eligible_users, left_on="ENTITY", right_on="user_id", how="inner")
    .merge(featured_items, left_on="CLASS", right_on="item_id", how="inner")
    .sort_values(["ENTITY", "SCORE"], ascending=[True, False])
    [["ENTITY", "CLASS", "SCORE"]]
)
```

Each remaining row is an allowed item candidate for one currently eligible customer, ordered for a possible purchase in the next 14 days. Use the rows to select product cards for that campaign. Recheck permission and product availability against the authoritative systems before sending, since either can change after scoring. The query can generate rows for customers who cannot receive email, and the filters can leave a customer with fewer than 12 items or none. This example does not claim that the model predicts email opens or that sending the email causes a purchase.