Shopify Flow: Triggers & Actions Reference
Complete reference of all Joy Loyalty triggers and actions available in Shopify Flow, with payload properties, plan requirements, and ready-to-use flow templates.
This feature is available for: Essential and above
Overview
Joy Loyalty exposes a set of triggers (events fired by Joy) and actions (tasks Joy can perform) inside Shopify Flow. Use them to build automated loyalty workflows — no code required.
This page is a complete reference. For step-by-step setup, see Integrate with Shopify Flow.
Trigger data properties
Every Joy trigger passes a common set of customer fields plus event-specific fields. When connecting to an email app (e.g. Klaviyo) through Shopify Flow, no variable dropdown is shown — you must type the property names manually. The tables below list every field for each trigger.
Klaviyo template syntax: Properties from Shopify Flow are available as event properties in Klaviyo. For multi-word property names, use the lookup filter: {{ event|lookup:'Customer email' }}. For single-word or underscored names, use dot notation: {{ event.customer_id }}.
Common fields (included in every trigger)
| Property name | Description | Example |
|---|---|---|
Customer email | Customer's email address | [email protected] |
Customer first name | First name | Jane |
Customer last name | Last name | Doe |
Customer points | Current point balance | 350 |
customer_id | Shopify customer numeric ID | 6123456789 |
Earn points
Extra fields beyond the common set:
| Property name | Description |
|---|---|
Program name | Name of the earning program that awarded points |
Earned points | Number of points earned in this activity |
Created at | Timestamp of the earn event |
Admin manual point adjustment
| Property name | Description |
|---|---|
Adjusted points | Points added or subtracted |
Adjustment reason | Reason entered by the admin |
Created at | Timestamp of the adjustment |
Customer has enough points for reward
| Property name | Description |
|---|---|
Program id | ID of the qualifying reward program |
Program name | Name of the reward program |
Program min point | Minimum points required to redeem |
Redeem points
| Property name | Description |
|---|---|
Redeemed points | Points spent on this redemption |
Discount code | The discount code generated |
POS point redemption
| Property name | Description |
|---|---|
Redeemed points | Points redeemed at POS |
Discount code | The discount code generated |
30 / 7 / 3 days before point expiration
| Property name | Description |
|---|---|
Customer points expire | Number of points that will expire |
Upon point expiration
| Property name | Description |
|---|---|
Customer points expire | Number of points that just expired |
7 days before customer's birthday
| Property name | Description |
|---|---|
Customer birthday date | Day of the month (e.g. 14) |
Customer birthday month | Month number (e.g. 7 for July) |
Customer's birthday
| Property name | Description |
|---|---|
Customer birthday date | Day of the month |
Customer birthday month | Month number |
Discount code | Birthday reward code (if a birthday reward is configured) |
VIP tier achieved
| Property name | Description |
|---|---|
Tier name | Name of the tier just achieved |
Discount code | Tier reward code (if configured) |
VIP Tier downgraded / VIP Tier reset
Uses common fields only. No extra properties.
Pre-Tier Demotion / Reset Reminders (4w / 2w / 1d)
Uses common fields only. No extra properties.
Customer comment on Instagram
Fires when Joy detects a customer comment on one of your monitored Instagram posts.
| Field | Type | Description |
|---|---|---|
post_id | string | The Instagram post the user commented on |
post_url | string | Direct link to the post |
comment_id | string | The comment identifier |
comment_text | string | The text of the comment |
is_first_comment | boolean | true if this is the user's first comment on this post, false otherwise |
comment_count | number | Total number of comments this user has posted on this post, including this one |
commented_at | datetime | When the comment was created |
Use is_first_comment to keep automated DMs from spamming users who comment repeatedly on the same post. In Shopify Flow, add a Condition after the trigger: only continue when is_first_comment equals true. Alternatively, use comment_count to branch on a custom threshold (e.g., only run on the 3rd comment onwards).
Customer commented on Instagram Live
Fires when Joy detects a customer comment on your Instagram Live broadcast and awards points.
| Field | Type | Description |
|---|---|---|
Comment username | string | The commenter's Instagram username |
Comment text | string | Text content of the live comment |
Points earned | number | Points earned from this live comment |
Live video id | string | ID of the Instagram Live video |
is_first_comment | boolean | true if this is the customer's first comment on this Live video |
Timestamp | datetime | When the comment was processed (ISO 8601) |
Live comments can't be auto-replied to via the Instagram API — Joy only sends DM notifications and awards points. Use is_first_comment to keep automated DMs from repeating for customers who comment multiple times during the same broadcast.
Customer joined loyalty program
Fires whenever a customer joins your loyalty program for the first time — via the widget, sign-up button, POS, or any custom entry point.
| Property name | Description | Example |
|---|---|---|
customer_id | Shopify customer numeric ID | 6123456789 |
Customer email | Email of the joining customer | [email protected] |
Customer first name | First name | Jane |
Customer last name | Last name | Doe |
Customer phone | Phone number (if provided) | +1 555-0100 |
Joined at | Timestamp the customer joined (ISO 8601) | 2026-04-17T10:22:00Z |
Initial points | Points granted on join, if a Sign-up reward is configured | 100 |
Common use cases: send a welcome email with the first earning opportunity, auto-tag the customer in Shopify, sync to Klaviyo / HubSpot, or branch downstream flows based on initial points.
Referral for friend complete
Fires for the referrer when their friend completes a qualifying order.
| Property name | Description |
|---|---|
Referrer email | Email of the referring customer (same as Customer email) |
Referrer reward type | Type of reward given (e.g. points, coupon) |
Referrer reward | Value of the reward |
order_id | Shopify order ID of the friend's order |
Referee claim reward
Fires for the new customer when they claim their referral reward.
| Property name | Description |
|---|---|
Discount code | The reward code issued to the referee |
Referrer email | Email of the friend who referred them |
Milestone reward ready to claim
Fires when a customer reaches a milestone whose reward they have to pick themselves, so the reward is sitting unclaimed in the loyalty widget.
| Property name | Description |
|---|---|
Program name | Name of the milestone program |
Milestone name | Name of the milestone step the customer just reached |
Milestone number | Position of the step within the program, starting at 1 |
Milestone value | Target value of the step (orders, amount spent, points, referrals…) |
Rewards | The rewards the customer can choose from, comma separated |
Max rewards to select | How many of those rewards the customer is allowed to pick |
Claim link | Link that opens the loyalty widget on the Milestones screen so they can claim |
Triggers — when they fire
Points
| Trigger | When it fires |
|---|---|
| Earn points | A customer earns points from any earning activity |
| Admin manual point adjustment | An admin adds or deducts points manually from the customer profile |
| Customer has enough points for reward | A customer's balance crosses the minimum threshold to redeem a reward |
| Redeem points | A customer redeems points for a discount |
| POS point redemption | A customer redeems points at a physical POS location |
Point expiration
| Trigger | When it fires |
|---|---|
| 30 days before the point expiration date | 30 days before a customer's points are set to expire |
| 7 days before the point expiration date | 7 days before expiration |
| 3 days before the point expiration date | 3 days before expiration |
| Upon point expiration | The moment a customer's points expire |
Point expiration triggers only fire if you have point expiration enabled. Go to Settings > Points to configure it.
Birthday
| Trigger | When it fires |
|---|---|
| 7 days before customer's birthday | 7 days before the customer's saved birthday |
| Customer's birthday | On the customer's birthday |
VIP Tiers
| Trigger | When it fires |
|---|---|
| VIP tier achieved | A customer reaches a new VIP tier |
| VIP Tier downgraded | A customer drops to a lower tier |
| VIP Tier reset | A customer's tier resets to the starting tier |
| 4-week Pre-Tier Demotion Reminder | 4 weeks before scheduled demotion |
| 2-week Pre-Tier Demotion Reminder | 2 weeks before demotion |
| 1-day Pre-Tier Demotion Reminder | 1 day before demotion |
| 4-week Pre-Tier Reset Reminder | 4 weeks before scheduled tier reset |
| 2-week Pre-Tier Reset Reminder | 2 weeks before reset |
| 1-day Pre-Tier Reset Reminder | 1 day before reset |
Demotion and reset reminders only fire when you have a tier evaluation period configured in Joy's VIP Tier settings.
Referrals
| Trigger | When it fires |
|---|---|
| Referral for friend complete | A referred friend places their first qualifying order |
| Referee claim reward | The new customer claims their referral reward |
Social activity
| Trigger | When it fires |
|---|---|
| Customer comment on Instagram | A customer comments on one of your monitored Instagram posts |
| Customer commented on Instagram Live | A customer comments on your Instagram Live broadcast |
Membership
| Trigger | When it fires |
|---|---|
| Customer joined loyalty program | A customer joins the loyalty program for the first time (widget sign-up, POS, custom entry) |
Milestones
| Trigger | When it fires |
|---|---|
| Milestone reward ready to claim | A customer reaches a milestone step that lets them pick their own reward, so the reward is waiting for them |
This trigger fires once per customer per milestone, at the moment the milestone is reached. Milestone steps that grant their reward automatically do not fire it, inactivity milestones do not fire it, and relaunching a program does not re-announce rewards that are already waiting. See When customers pick their own reward.
Both Instagram comment triggers expose is_first_comment and comment_count so you can limit automated responses to the first comment per user per post — essential for avoiding spam when a user comments many times.
Actions
Actions are tasks that Joy performs when called from a Shopify Flow. All actions require the integration to be enabled in Joy > Integrations > Shopify Flow.
Points
Add point — Adds points to a customer's balance.
| Field | Required | Description |
|---|---|---|
email | ✅ | Customer's email address |
point | ✅ | Points to add (positive integer) |
reason | ✅ | Label shown in the customer's activity log |
Subtract point — Deducts points (will not go below zero).
| Field | Required | Description |
|---|---|---|
email or customer_id | ✅ | Customer email or Shopify customer GID |
point | ✅ | Points to subtract |
reason | — | Internal note for the activity log |
Store credit
Requires granting an additional Shopify permission. When you enable the integration, a banner will prompt you to grant access.
Adjust store credit
| Field | Required | Description |
|---|---|---|
customer_identification | ✅ | Customer email or Shopify customer GID |
credits_calculation | ✅ | Credit amount (e.g. 10.00 or a Flow variable) |
reason | — | Internal note |
expiration_days | — | Days until credit expires (leave blank for no expiry) |
VIP Tiers
Tier actions require Advanced plan or above.
Assign to Tier — Assigns a customer directly to an exclusive VIP tier.
| Field | Required | Description |
|---|---|---|
customer_identifier | ✅ | Customer email or Shopify customer GID |
exclusive_tier_identifier | ✅ | The tier's name or ID in Joy |
Unassign exclusive tier — Returns customer to their points-based tier.
| Field | Required | Description |
|---|---|---|
customer_identifier | ✅ | Customer email or Shopify customer GID |
Coupons
Reward by program — Rewards a customer from any active Joy program. Most programs only need Customer + Reward program identifier — a couple of program types need one extra field, see the table below.
| Field | Required | Description |
|---|---|---|
customer | ✅ | Shopify customer (Flow's built-in customer picker) |
reward_program_identifier | ✅ | Program ID or Program name in Joy |
admin_note | — | Optional note for internal reference |
program_input (Extra input) | — | Required only for: Google Maps review (the review URL), Submit receipt (image URL(s), comma or newline separated), Survey/Form (the submitted content). Leave blank for every other program type. |
milestone_value | — | Required only for Milestone programs — the milestone value to reward (e.g. 12000). Leave blank for non-milestone programs. |
Which program types this action supports
This action dispatches by how the target program's reward is configured, not by which earning event it is — the same program type behaves differently depending on its own reward setting:
| Program's reward setting | What this action does |
|---|---|
| Points — Sign up, Newsletter sign-up, Social (Facebook, Instagram follow, Twitter/X, Pinterest, TikTok, YouTube, Discord/Telegram/WhatsApp/Line/Reddit), Interact website / Streak, Google Maps review, Submit receipt, Survey / Form, Member anniversary, or Birthday when set to reward Points | Awards points, using that program's normal earn flow |
| Discount (amount / percentage / Buy X Get Y / free gift / store credit) — any of the above programs when instead configured with a discount reward, plus dedicated Redeeming/Discount programs | Issues a coupon for free — no points are deducted (same mechanism used for VIP tier rewards, not a normal redemption) |
| Milestone | Needs milestone_value — grants the reward for that specific milestone directly (whichever type it is), regardless of the customer's tracked progress toward it |
Joy deduplicates by customer + program, so if the same Flow condition matches more than once for a customer (e.g. two qualifying orders in the same sale), they're still only rewarded once.
Not available through this action:
- Custom programs (purchase condition, page visit, custom trigger, its own Shopify Flow trigger) — use the Trigger custom activity action below instead.
- Instagram engagement (comment, story mention/reply, live comment) — already tracked and rewarded automatically by Joy's Instagram integration; routing it through this action too would double-reward.
- Place order / Place order subscription — already handled automatically by Joy's native order webhook; calling this action for them is a no-op.
- Reviews from third-party review apps (Judge.me, Air Reviews, etc.) — the review app is the source of truth for approval status, which this action has no way to check.
Revoke coupon — Voids a discount code and refunds any points spent.
| Field | Required | Description |
|---|---|---|
customer_id | ✅ | Shopify customer GID |
discount_code | ✅ | The exact code to revoke |
admin_note | — | Internal note |
Membership
Join loyalty program — Converts a guest to active member status.
| Field | Required | Description |
|---|---|---|
customer_id | ✅ (or customer_identifier) | Shopify customer GID |
customer_identifier | ✅ (or customer_id) | Customer email, ID, or GID |
Exclude from loyalty program — Removes a customer from the program.
| Field | Required | Description |
|---|---|---|
customer_id | ✅ (or customer_identifier) | Shopify customer GID |
customer_identifier | ✅ (or customer_id) | Customer email, ID, or GID |
reason | ✅ | Reason for exclusion |
Custom activity
Trigger custom activity — Fires a custom earning program inside Joy.
| Field | Required | Description |
|---|---|---|
action-key | ✅ | Action key from the custom program in Joy |
customer_id | ✅ | Shopify customer GID |
First create a Custom program in Joy > Earn points > Custom, then copy its action key into the Flow extension settings.
Flow Templates
1 — Birthday points + email (Klaviyo)
Goal: Give bonus points on a customer's birthday and send a personalised email.
Trigger: Customer's birthday
→ Action (Joy): Add point
email: {{ customer.email }}
point: 200
reason: Birthday bonus
→ Action (Klaviyo): Send email
To: Customer email
Subject: Happy birthday, {{ event|lookup:'Customer first name' }}!
Body variables:
{{ event|lookup:'Customer email' }}
{{ event|lookup:'Customer first name' }}
{{ event|lookup:'Customer points' }}
{{ event|lookup:'Discount code' }}2 — Point expiration reminder series
Goal: Warn customers before points expire with escalating urgency.
Trigger: 30 days before the point expiration date
→ Action (Klaviyo): Send email — "Your points expire in 30 days"
{{ event|lookup:'Customer points expire' }} points expiring
Trigger: 7 days before the point expiration date
→ Action (Klaviyo): Send email — "Hurry — 7 days left"
Trigger: Upon point expiration
→ Action (Klaviyo): Send email — "Your points have expired"3 — VIP tier upgrade congratulations
Goal: Celebrate a tier upgrade with a bonus and email.
Trigger: VIP tier achieved
→ Action (Joy): Add point
email: {{ customer.email }}
point: 500
reason: Welcome bonus — new tier
→ Action (Klaviyo): Send email
{{ event|lookup:'Tier name' }}
{{ event|lookup:'Customer points' }}
{{ event|lookup:'Discount code' }}4 — Pre-demotion rescue
Goal: Motivate customers to spend before they lose their tier.
Trigger: 4-week Pre-Tier Demotion Reminder
→ Action (Klaviyo): Send email — "You're at risk of losing your tier"
{{ event|lookup:'Customer first name' }}
{{ event|lookup:'Customer points' }}
Trigger: 1-day Pre-Tier Demotion Reminder
→ Action (Klaviyo): Send email — "Last chance — tier demotion tomorrow"5 — Reward any review app
Goal: Give points when a customer submits a review in any app that supports Shopify Flow (Loox, Okendo, Stamped, Yotpo, etc.).
Trigger: [Review App] — Review submitted
→ Action (Joy): Add point
email: {{ customer.email }}
point: 50
reason: Thanks for your review!See the individual integration guides (linked from the parent page) for app-specific trigger names.
6 — Auto-enrol new customers
Goal: Add customers to the loyalty program the moment they sign up.
Trigger: Customer created (native Shopify trigger)
→ Action (Joy): Join loyalty program
customer_id: {{ customer.id }}7 — Referral reward notification
Goal: Send the referrer a confirmation email when their friend's order is complete.
Trigger: Referral for friend complete
→ Action (Klaviyo): Send email
To: {{ event|lookup:'Referrer email' }}
Body variables:
{{ event|lookup:'Customer first name' }}
{{ event|lookup:'Referrer reward type' }}
{{ event|lookup:'Referrer reward' }}
{{ event|lookup:'Customer points' }}8 — Reward a flash-sale coupon that isn't usable until later
Goal: Reward customers who place a qualifying order during a flash sale with a free coupon that only becomes usable once the sale ends (so it can't be stacked on sale pricing).
Trigger: Order created (native Shopify trigger)
→ Condition: Order total ≥ [threshold]
→ Action (Joy): Reward by program
customer: {{ order.customer }}
reward_program_identifier: [Discount program ID]On the Discount program side, set Coupon validity → Usable from to a date after the sale ends — see Coupon validity. Customers see the coupon in their wallet as soon as they earn it, labeled "Active from [date]," and it unlocks automatically on that date.
FAQ
Which plan do I need?
Essential and above. Assign to Tier and Unassign exclusive tier require Advanced or above.
Why is my action not running?
Make sure the integration toggle is On in Joy > Integrations > Shopify Flow. This is the most common cause of silent failures.
Klaviyo doesn't show a variable picker — what do I type?
Use {{ event|lookup:'Property name' }} for any property with spaces in its name (see the property tables above). For single-word or underscored names like customer_id, you can use {{ event.customer_id }}.
Can I use multiple Joy actions in one Flow?
Yes. You can chain Joy actions — for example, add points and send a coupon in the same automation.
The "Adjust store credit" action isn't available — why?
It requires an additional Shopify permission. Enable the integration in Joy and click Grant access in the blue banner that appears.
Can I test triggers without real events?
Use Shopify Flow's built-in Run test feature, or use the Admin manual point adjustment trigger as a safe sandbox since you control exactly when it fires.
Does "Reward by program" deduct points when I target a redeeming/discount program?
No — a reward issued this way is free. It uses the same mechanism as VIP tier rewards, so no points are deducted from the customer, unlike a normal points redemption.
What if the same Flow condition matches twice for one customer?
Joy rewards once per customer per program regardless of how many times the condition matches — for example, two qualifying orders in the same sale still only produce one coupon.