# Shopify Flow: Triggers & Actions Reference

{% hint style="info" %}
This feature is available for: **Essential and above**
{% endhint %}

### 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](/integrations/integrate-with-shopify-flow.md).

***

### 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.

{% hint style="info" %}
**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 }}`.
{% endhint %}

#### Common fields (included in every trigger)

| Property name         | Description                 | Example            |
| --------------------- | --------------------------- | ------------------ |
| `Customer email`      | Customer's email address    | `jane@example.com` |
| `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                                                   |

{% hint style="info" %}
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).
{% endhint %}

#### Customer commented on Instagram Live

Fires when Joy detects a customer comment on your Instagram **Live** broadcast. The payload follows the same shape as the "Customer comment on Instagram" trigger above, including `is_first_comment` and `comment_count`.

#### Customer joined loyalty program <a href="#join-loyalty-trigger" id="join-loyalty-trigger"></a>

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                             | `jane@example.com`     |
| `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 |

***

### 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                |

{% hint style="info" %}
Point expiration triggers only fire if you have point expiration enabled. Go to **Settings > Points** to configure it.
{% endhint %}

#### 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                            |

{% hint style="info" %}
Demotion and reset reminders only fire when you have a tier evaluation period configured in Joy's VIP Tier settings.
{% endhint %}

#### 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) |

{% hint style="info" %}
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.
{% endhint %}

***

### 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

{% hint style="info" %}
Requires granting an additional Shopify permission. When you enable the integration, a banner will prompt you to grant access.
{% endhint %}

**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

{% hint style="info" %}
Tier actions require **Advanced plan or above**.
{% endhint %}

**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 coupon** — Generates a discount coupon from a reward program.

| Field                       | Required | Description                      |
| --------------------------- | -------- | -------------------------------- |
| `customer_id`               | ✅        | Shopify customer GID             |
| `reward_program_identifier` | ✅        | Reward program name or ID in Joy |
| `admin_note`                | —        | Internal note                    |

**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                      |

{% hint style="info" %}
First create a **Custom program** in Joy > Earn points > Custom, then copy its action key into the Flow extension settings.
{% endhint %}

***

### 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' }}
```

***

### 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.joy.so/integrations/integrate-with-shopify-flow/shopify-flow-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
