Product recommendations
Joryio's recommendation engine picks per-customer items for your emails (and, later, in-app messages and journeys). It is deliberately transparent - you decide what it learns from:
- Item source - your synced store products (Shopify/WooCommerce) or any Custom Entity that holds a catalog.
- Training signals - which events teach the engine, each with a weight (e.g.
purchase×5,add_to_cart×2,product_viewed×1 - any events, including your custom ones). The item id property tells the engine which event property carries the item (e.g.productId); when an event uses a different property (say anad_viewevent carryingad_id), set it per signal - each signal row has its own optional property that overrides the model default. - Selection (optional) - for entity-catalog sources, pick a selection to narrow what the model may recommend (e.g. only one brand or location). Static filters only - per-recipient filter values can't resolve at ranking time. A missing/broken selection falls back to the full catalog rather than blanking the email.
- Training window and an option to never recommend items the customer already purchased.
Multiple models
A workspace can hold several named models, each with its own type, source and signals - create them under Settings → Recommendations and pick one per product block in the email editor (Source: Recommended → Model). One model is marked as the default and is used when a block doesn't pick one.
| Type | What each recipient gets | Training |
|---|---|---|
| Personalized | Items matched to their own recent activity (item-to-item affinity) | Nightly + Train now |
| Most popular | The same bestseller list for everyone, weighted by your signals | Nightly + Train now |
| Trending now | What's hot over the last 7 days | None - computed live |
| Recently viewed | Their own latest items (falls back to Trending for new customers) | None - computed live |
How it learns
Training (nightly for enabled configs, or Train now) runs two passes over your event stream: weighted popularity per item, and item-to-item affinity - which items the same customers engage with together, normalized so niche pairs aren't drowned out by bestsellers.
Learning from outcomes (v2 ranker)
Once a model has real serving outcomes (recommendations served → items bought), a second-stage ranker trains on them nightly and starts re-ordering each recipient's candidates by learned conversion probability - "when we show X to customers like this, they buy". It includes an exploration slot so new items keep getting a fair chance to earn data. The ranker activates per model only after enough outcomes exist; until then (and whenever it's unreachable) the engine's standard ordering is used, so nothing ever breaks. Sends carry a flag distinguishing ranked from standard ordering, so their performance stays comparable.
Performance analytics
Once a model's recommendations go out in real sends, its page shows the last 30 days: how many recommendations were served, to how many recipients, the share who clicked the carrying message, and the share who bought a recommended item within 7 days of receiving it (attributed via the recommendation.served platform event).
How it serves
At send time each recipient's recent activity votes for related items; customers without history get current bestsellers. Configure it under Settings → Recommendations, then use it in the email editor's product block by choosing Source: Recommended with a count.