Skip to content
Last updated

🏷️ Metafields & Tags

Shopify Metafields & Tags Reference

Appstle Loyalty uses Shopify metafields and tags to store loyalty program data, power storefront widgets, sync product reviews, and enable automation workflows. This reference covers every metafield and tag — what it contains, when it's set, and how to use it in your integration.


📦 Metafields Overview

Appstle Loyalty uses three namespaces across multiple resource types:

NamespaceResourcesVisibilityPurpose
appstle_loyaltyShop, CustomerPublic (readable by any app/theme)Loyalty program configuration, customer loyalty profiles
$app:appstle_loyaltyCustomerPrivate (only readable by this app)Customer reward discount codes for checkout
appstle_reviewProduct, ShopPublicProduct reviews, ratings, and carousel data

Private namespace note: The $app:appstle_loyalty namespace uses Shopify's app-owned metafield protection. Metafields in this namespace can only be read and written by the Appstle Loyalty app itself — not by themes, Liquid templates, or other apps.


🏪 Shop Metafields — Loyalty Program (appstle_loyalty)

These metafields store the complete loyalty program configuration and are used by the storefront widget to render the loyalty experience. They are written by SubscribeItScriptUtils.writeShopMetafield() whenever a merchant saves settings.

When updated: On every settings save in the Appstle admin, and when point rules or VIP tiers are modified. Updates are synchronous (immediate).

Core Configuration

KeyTypePurpose
app_urlstringApp base URL for widget communication
proxy_path_prefixstringCustom proxy path prefix (default: apps/loyalty)
public_domainstringStore's public domain name
shop_namestringStore name from Shopify
currencystringISO currency code (e.g., USD, EUR)
store_front_access_tokenstringShopify Storefront API access token

Widget Configuration

KeyTypePurpose
bundle_js_pathurlCDN URL for widget JS bundle (with version params)
bundle_css_pathurlCDN URL for widget CSS bundle (with version params)
widget_settingjsonFull widget configuration object (colors, layout, positioning, etc.)
shop_labelsjsonWidget label translations (i18n support)

Points Configuration

KeyTypePurpose
pointRoundTypestringPoint rounding strategy: NO_ROUND, ROUND_DOWN, or ROUND_UP
point_earn_rulesjsonArray of all active point earn rules
point_redeem_rulesjsonArray of all active point redeem rules

Example: point_earn_rules

[
  {
    "id": 123,
    "type": "PURCHASE",
    "pointsPerDollar": 5,
    "minimumOrderAmount": 0,
    "enabled": true
  },
  {
    "id": 124,
    "type": "SIGNUP",
    "fixedPoints": 100,
    "enabled": true
  },
  {
    "id": 125,
    "type": "BIRTHDAY",
    "fixedPoints": 200,
    "enabled": true
  }
]

Example: point_redeem_rules

[
  {
    "id": 456,
    "type": "FIXED_AMOUNT",
    "pointsCost": 500,
    "discountValue": 5.00,
    "discountType": "FIXED_AMOUNT",
    "enabled": true
  },
  {
    "id": 457,
    "type": "PERCENTAGE",
    "pointsCost": 1000,
    "discountValue": 10,
    "discountType": "PERCENTAGE",
    "maxDiscountAmount": 50.00,
    "enabled": true
  }
]

Feature Flags

KeyTypePurpose
enable_inactive_customerbooleanAllow tracking inactive customers in the program
has_dedicated_page_accessbooleanAccess to dedicated loyalty page feature
allow_customer_opt_inbooleanAllow customer self-opt-in to the loyalty program
enable_discount_to_apply_automaticallybooleanAuto-apply reward discounts at checkout
show_store_credit_rewardsbooleanShow store credit rewards in the widget
birthdate_formatstringExpected birthdate format (MM/DD, DD/MM, etc.)

Referral Configuration

KeyTypePurpose
referral_enabledbooleanReferral program enabled flag
referral_loyaltyjsonReferral config (discount type, tags, amounts)

Example: referral_loyalty

{
  "referrerDiscountType": "PERCENTAGE",
  "referrerDiscountValue": 10,
  "referredDiscountType": "FIXED_AMOUNT",
  "referredDiscountValue": 5.00,
  "referrerPoints": 500,
  "referredPoints": 200
}

VIP Tier Configuration

KeyTypePurpose
vip_tier_enabledbooleanVIP tier program enabled flag
vip_tiersjsonArray of VIP tier definitions
vip_rewardsjsonVIP tier-specific point redeem rules
vip_point_rewardsjsonVIP tier-specific point earn rules
vip_tier_settingjsonVIP tier configuration object

Example: vip_tiers

[
  {
    "id": 1,
    "name": "Silver",
    "threshold": 0,
    "icon": "🥈",
    "additionalTags": "silver-member"
  },
  {
    "id": 2,
    "name": "Gold",
    "threshold": 1000,
    "icon": "🥇",
    "additionalTags": "gold-member, premium-support"
  },
  {
    "id": 3,
    "name": "Platinum",
    "threshold": 5000,
    "icon": "💎",
    "additionalTags": "platinum-member, priority-shipping, premium-support"
  }
]

Points Expiration

KeyTypePurpose
points_expiration_settingjsonPoint expiration config (interval and type)
{
  "enabled": true,
  "interval": 12,
  "intervalType": "MONTH"
}

Metafield Deletion

Shop metafields can be removed via MiscellaneousResource.removeShopMetafield() — this is used when resetting or disabling features.


👤 Customer Metafields — Loyalty Profile (appstle_loyalty)

appstle_loyalty / customer_loyalty

PropertyValue
Typejson
ResourceCustomer
VisibilityPublic (readable by themes and other apps)
Set bySubscribeItScriptUtils.writeCustomerMetafield() (loyalty-l / Lambda)
Updated whenAfter every loyalty event: point earn, point redeem, VIP tier change, referral, social engagement, etc.
Update mechanismProcessed by AWS Lambda (loyalty-l), updates are near real-time

Important: This metafield is set only by the Lambda processor (loyalty-l), not by the main loyalty app. It's updated after every loyalty event.

{
  "availablePoints": 1250,
  "pendingPoints": 100,
  "redeemedPoints": 500,
  "creditedPoints": 1850,
  "vipTier": {
    "id": 2,
    "name": "Gold"
  },
  "achievableTierId": 3,
  "activeRewards": [
    {
      "discountCode": "REWARD-XYZ789",
      "discountType": "PERCENTAGE",
      "discountValue": 10
    }
  ],
  "socialMediaEngagement": {
    "facebook": true,
    "twitter": false,
    "instagram": true,
    "youtube": false,
    "tiktok": false,
    "pinterest": false,
    "newsletter": true,
    "sms": false,
    "accountCreation": true,
    "sharing": false
  },
  "referralInfo": {
    "referralLink": "https://store.myshopify.com/?ref=abc123",
    "completedReferrals": 3
  },
  "customerStatus": "ACTIVE",
  "dateOfBirth": "1990-05-15",
  "storeCreditBalance": 25.00,
  "lastActivityDate": "2025-03-20T14:30:00Z",
  "spentAmount": 450.75
}

🔒 Customer Metafields — Reward Codes ($app:appstle_loyalty)

$app:appstle_loyalty / customer_rewards

PropertyValue
Typejson
ResourceCustomer
VisibilityPrivate — only readable by the Appstle Loyalty app
Set byCommonUtils.syncCustomerRewardMetafield() (loyalty) and SubscribeItScriptUtils.syncCustomerRewardMetafield() (loyalty-l)
Updated whenCustomer redeems points for a reward, reward expires, or reward is used
PurposeStores active discount codes for Shopify checkout discount functions
{
  "rewards": [
    { "discountCode": "REWARD-ABC123" },
    { "discountCode": "REWARD-DEF456" }
  ]
}

Why private? This metafield uses the $app: prefix to prevent external access. It contains discount codes that should only be validated by the Shopify discount function, not exposed to themes or third-party apps.


⭐ Product Metafields — Reviews (appstle_review)

Product review metafields are set on individual Product resources and on the Shop resource (for carousel displays).

Set by: SubscribeItScriptUtils.createOrUpdateProductMetafield() in both loyalty and loyalty-l repos.

Updated when: A review is approved, updated, or deleted. Updates are synchronous in the main app and near real-time from Lambda.

Per-Product Metafields

KeyTypePurpose
product_reviewsjsonArray of approved reviews for the product detail page (paginated, max 5 per page)
total_reviewsintegerTotal review count for the product
ratingratingOverall product rating (Shopify native rating type: value, scale_min=1, scale_max=5)
product_rating_detailsjsonBreakdown by star rating (map of rating → count)

Example: product_reviews

[
  {
    "id": 789,
    "author": "John D.",
    "rating": 5,
    "title": "Amazing product!",
    "body": "This is the best coffee I've ever had.",
    "createdAt": "2025-03-15T10:00:00Z",
    "verified": true
  }
]

Example: rating (Shopify native rating type)

{
  "value": "4.5",
  "scale_min": "1",
  "scale_max": "5"
}

Example: product_rating_details

{
  "5": 42,
  "4": 18,
  "3": 7,
  "2": 2,
  "1": 1
}
KeyTypePurpose
carousel_product_reviewsjsonRecent/featured reviews for the homepage carousel widget (max 15 reviews)
carousel_total_reviewsintegerTotal count of reviews in the carousel
carousel_ratingratingOverall rating for the carousel display (Shopify native rating type)

🏷️ Tags Overview

Appstle Loyalty applies tags to Customer resources only. No tags are applied to orders or products.

All tags are applied using the Shopify GraphQL Admin API (TagsAddMutation / TagsRemoveMutation).


👤 Customer Tags

VIP Tier Name Tags

PropertyValue
ResourceCustomer
FormatDynamic — the VIP tier's name (e.g., Silver, Gold, Platinum)
Applied whenCustomer achieves or is promoted to a VIP tier (automatic calculation or manual assignment)
Removed whenCustomer's tier changes (upgrade, downgrade, or removal)
Mutual exclusivityOnly the current tier's name tag is active — previous tier name tags are removed

When tier tags are applied:

  • Automatic VIP tier calculation (based on spend, points, or order count thresholds)
  • Manual tier assignment by merchant
  • Referral flow VIP assignment
  • Shopify Flow trigger VIP assignment
  • Bulk operations VIP assignment

Additional VIP Tier Tags (Merchant-Configured)

PropertyValue
ResourceCustomer
FormatComma-separated tags configured per tier in the additionalTags field
Applied whenAlong with the tier name tag when a customer achieves a VIP tier
Removed whenCustomer leaves the tier (upgrade, downgrade, or removal)
ConfigurationSet per VIP tier in the Appstle admin under VIP Tiers

Example

A "Gold" tier configured with additionalTags = "premium-member, vip-support" will apply three tags when a customer reaches Gold:

  1. Gold (the tier name)
  2. premium-member (additional tag)
  3. vip-support (additional tag)

When the customer upgrades to Platinum, all three Gold tags are removed and replaced with Platinum's tags.

Referral Tags

PropertyValue
ResourceCustomer
FormatTwo tags per referral relationship
Applied whenA referral offer is accepted by both parties
RemovedNever (referral tags are permanent)
Tag PatternApplied ToPurpose
referral:{referralCustomerId}The referrerIdentifies the referred customer
referred:{originalCustomerId}The referred customerIdentifies who referred them

Example

Customer A (ID: 1111) refers Customer B (ID: 2222):

  • Customer A gets tag: referral:2222
  • Customer B gets tag: referred:1111

Product Review Tag

PropertyValue
ResourceCustomer
FormatWrote Appstle Web Review (static string)
Applied whenA new Shopify customer is created via product review submission (only if the customer didn't previously exist in Shopify)
RemovedNever (permanent tag)

📊 Summary Tables

All Metafields at a Glance

#ResourceNamespaceKeyTypeVisibility
1Shopappstle_loyaltyapp_urlstringPublic
2Shopappstle_loyaltyproxy_path_prefixstringPublic
3Shopappstle_loyaltypublic_domainstringPublic
4Shopappstle_loyaltyshop_namestringPublic
5Shopappstle_loyaltycurrencystringPublic
6Shopappstle_loyaltypointRoundTypestringPublic
7Shopappstle_loyaltypoint_earn_rulesjsonPublic
8Shopappstle_loyaltypoint_redeem_rulesjsonPublic
9Shopappstle_loyaltybundle_js_pathurlPublic
10Shopappstle_loyaltybundle_css_pathurlPublic
11Shopappstle_loyaltywidget_settingjsonPublic
12Shopappstle_loyaltyshop_labelsjsonPublic
13Shopappstle_loyaltyenable_inactive_customerbooleanPublic
14Shopappstle_loyaltyhas_dedicated_page_accessbooleanPublic
15Shopappstle_loyaltyallow_customer_opt_inbooleanPublic
16Shopappstle_loyaltyenable_discount_to_apply_automaticallybooleanPublic
17Shopappstle_loyaltystore_front_access_tokenstringPublic
18Shopappstle_loyaltybirthdate_formatstringPublic
19Shopappstle_loyaltyshow_store_credit_rewardsbooleanPublic
20Shopappstle_loyaltyreferral_enabledbooleanPublic
21Shopappstle_loyaltyreferral_loyaltyjsonPublic
22Shopappstle_loyaltyvip_tier_enabledbooleanPublic
23Shopappstle_loyaltyvip_tiersjsonPublic
24Shopappstle_loyaltyvip_rewardsjsonPublic
25Shopappstle_loyaltyvip_point_rewardsjsonPublic
26Shopappstle_loyaltyvip_tier_settingjsonPublic
27Shopappstle_loyaltypoints_expiration_settingjsonPublic
28Customerappstle_loyaltycustomer_loyaltyjsonPublic
29Customer$app:appstle_loyaltycustomer_rewardsjsonPrivate
30Productappstle_reviewproduct_reviewsjsonPublic
31Productappstle_reviewtotal_reviewsintegerPublic
32Productappstle_reviewratingratingPublic
33Productappstle_reviewproduct_rating_detailsjsonPublic
34Shopappstle_reviewcarousel_product_reviewsjsonPublic
35Shopappstle_reviewcarousel_total_reviewsintegerPublic
36Shopappstle_reviewcarousel_ratingratingPublic

All Tags at a Glance

#ResourceTag PatternWhen AppliedPermanent?
1Customer{VIP tier name} (dynamic)VIP tier assignmentNo (swapped on tier change)
2Customer{additionalTags} (merchant-configured per tier)VIP tier assignmentNo (swapped on tier change)
3Customerreferral:{customerId} / referred:{customerId}Referral acceptanceYes
4CustomerWrote Appstle Web ReviewNew customer created via reviewYes

GraphQL Mutations Used

MutationPurpose
MetafieldsSetMutationCreate or update metafields on any resource
MetafieldsDeleteMutationDelete metafields
TagsAddMutationAdd tags to customers
TagsRemoveMutationRemove tags from customers

❓ FAQ

Can I read loyalty metafields from my Liquid theme?

Yes — metafields in the appstle_loyalty and appstle_review namespaces are public. Access them in Liquid via {{ customer.metafields.appstle_loyalty.customer_loyalty }} or {{ product.metafields.appstle_review.rating }}. However, customer_rewards in the $app:appstle_loyalty namespace is private and not accessible in Liquid.

How quickly are customer loyalty metafields updated?

Customer loyalty metafields are updated by the Lambda processor (loyalty-l) after every loyalty event. Updates are near real-time — typically within a few seconds.

What happens to VIP tier tags when a customer is upgraded?

When a customer's VIP tier changes, the old tier's name tag and all its additionalTags are removed, and the new tier's name tag and additionalTags are added. Only one tier's tags are active at a time.

Can other apps read the customer_rewards discount codes?

No. The customer_rewards metafield uses the $app:appstle_loyalty namespace, which is a private app-owned namespace. Only the Appstle Loyalty app can read and write it. This protects discount codes from being exposed to unauthorized apps.

How do product review ratings work with Shopify's native rating type?

The rating metafield uses Shopify's native rating type (not JSON), which integrates directly with Shopify's built-in rating display, Google rich results, and other SEO features. The value is on a scale of 1 to 5.