Webhook Events
Available topics
Total Events Available: 19 webhook topics covering all major loyalty program interactions
Joy Loyalty supports the following webhook topics for real-time event notifications:
| Topic | Description | Trigger |
|---|---|---|
points/earned | Customer earns points | When points are added to customer account |
points/redeemed | Customer redeems points | When points are used to redeem rewards |
points/expired | Points expired | When customer's points expire and are deducted |
points/about_to_expire_3_days | Points about to expire (3 days) | 3 days before points expiration |
points/about_to_expire_7_days | Points about to expire (7 days) | 7 days before points expiration |
points/about_to_expire_30_days | Points about to expire (30 days) | 30 days before points expiration |
customer/status_changed | Customer status changed | When customer joins, rejoins, or leaves loyalty program |
reward/coupon_used | Coupon used | When customer uses a Joy coupon to place an order |
tier/upgraded | Customer tier upgraded | When customer is upgraded to a higher tier |
tier/downgraded | Customer tier downgraded | When customer is demoted to a lower tier |
tier/reset | Tier reset | When customer's tier is reset according to scheduled reset |
tier/about_to_reset_4_weeks | Tier about to reset (4 weeks) | 4 weeks before tier reset |
tier/about_to_reset_2_weeks | Tier about to reset (2 weeks) | 2 weeks before tier reset |
tier/about_to_reset_1_day | Tier about to reset (1 day) | 1 day before tier reset |
referral/link_created | Referral link created | When customer creates a referral link for the first time |
referral/reward_earned | Referral reward earned | When referrer receives reward after referee completes order |
referral/referee_claimed | Referee claimed reward | When referee claims coupon reward |
birthday/reward_earned | Birthday reward earned | When customer receives birthday reward |
milestone/achieved | Milestone achieved | When customer achieves a milestone |
Webhook delivery
When a loyalty event occurs, Joy automatically sends a POST request to your registered webhook endpoints with the following characteristics:
- HTTP Method: POST
- Content-Type: application/json
- Timeout: 5 seconds maximum response time
- Retry Logic: Failed webhooks are retried with exponential backoff
- Security: All requests include HMAC signature for verification
Request headers
Every webhook request from Joy includes these headers:
Content-Type: application/json
X-Joy-Loyalty-Shop-Source-Id: your_shop_source_id
X-Joy-Loyalty-Hmac-Sha256: signature_hash
X-Joy-Loyalty-Topic: webhook_topicHeader Descriptions:
| Header | Description |
|---|---|
Content-Type | Always set to application/json |
X-Joy-Loyalty-Shop-Source-Id | Your shop's unique identifier in Joy system |
X-Joy-Loyalty-Hmac-Sha256 | HMAC-SHA256 signature for verifying authenticity |
X-Joy-Loyalty-Topic | The webhook topic that triggered this request |
Base payload structure
All webhook payloads include these common fields:
{
"webhookId": "unique_webhook_id",
"triggeredAt": "2024-01-15T10:30:00.000Z",
"customer": {
"email": "customer@example.com",
"name": "John Doe",
"shopifyCustomerId": "gid://shopify/Customer/123456"
},
"id": "activity_id",
"createdAt": "2024-01-15T10:30:00.000Z"
}Event payload examples
Points events
points/earned
{
"topic": "points/earned",
"shopDomain": "myshop.myshopify.com",
"timestamp": "2024-01-15T10:30:00.000Z",
"data": {
"customerId": "gid://shopify/Customer/123456",
"email": "customer@example.com",
"points": 100,
"totalPoints": 1500,
"source": "order",
"orderId": "gid://shopify/Order/789"
}
}points/redeemed
{
"topic": "points/redeemed",
"shopDomain": "myshop.myshopify.com",
"timestamp": "2024-01-15T10:30:00.000Z",
"data": {
"customerId": "gid://shopify/Customer/123456",
"email": "customer@example.com",
"pointsRedeemed": 500,
"remainingPoints": 1000,
"rewardType": "discount",
"rewardValue": "$5 OFF"
}
}points/expired
{
"webhookId": "activity_xyz789",
"triggeredAt": "2024-01-15T10:30:00.000Z",
"customer": {
"email": "customer@example.com",
"name": "John Doe",
"shopifyCustomerId": "gid://shopify/Customer/123456"
},
"id": "activity_xyz789",
"oldPoint": 500,
"newPoint": 0,
"type": "expire_point",
"createdAt": "2024-01-15T10:30:00.000Z"
}points/about_to_expire
{
"webhookId": "about_to_expire_customer123_1705312200000",
"triggeredAt": "2024-01-15T10:30:00.000Z",
"customer": {
"email": "customer@example.com",
"name": "John Doe",
"shopifyCustomerId": "gid://shopify/Customer/123456"
},
"id": "about_to_expire_customer123_1705312200000",
"type": "points_about_to_expire",
"point": 500,
"expiredAt": "2024-01-22T00:00:00.000Z",
"daysUntilExpiration": 7,
"createdAt": "2024-01-15T10:30:00.000Z"
}Customer events
customer/status_changed
{
"topic": "customer/status_changed",
"shopDomain": "myshop.myshopify.com",
"timestamp": "2024-01-15T10:30:00.000Z",
"data": {
"customerId": "gid://shopify/Customer/123456",
"email": "customer@example.com",
"firstName": "John",
"lastName": "Doe",
"type": "user_joined",
"tier": "Bronze"
}
}Possible type values:
user_joined: Customer joins loyalty program for the first timeuser_rejoined: Customer rejoins after leavinguser_excluded: Customer is excluded from loyalty program
Reward events
reward/coupon_used
{
"webhookId": "activity_xyz789",
"triggeredAt": "2024-01-15T10:30:00.000Z",
"customer": {
"email": "customer@example.com",
"name": "John Doe",
"shopifyCustomerId": "gid://shopify/Customer/123456"
},
"id": "activity_xyz789",
"type": "place_order_with_coupon",
"couponCode": "JOY-ABC123",
"orderId": 123456789,
"orderNumber": 1001,
"orderName": "#1001",
"orderSubTotal": "99.99",
"orderCurrency": "USD",
"programTitle": "10% Off Discount",
"redeemPoint": 500,
"createdAt": "2024-01-15T10:30:00.000Z"
}Tier events
tier/upgraded
{
"webhookId": "activity_xyz789",
"triggeredAt": "2024-01-15T10:30:00.000Z",
"customer": {
"email": "customer@example.com",
"name": "John Doe",
"shopifyCustomerId": "gid://shopify/Customer/123456"
},
"id": "activity_xyz789",
"type": "update_tier",
"oldTierId": "tier_bronze_123",
"oldTierName": "Bronze",
"newTierId": "tier_silver_456",
"newTierName": "Silver",
"tierPoint": 1500,
"createdAt": "2024-01-15T10:30:00.000Z"
}tier/downgraded
{
"webhookId": "activity_xyz789",
"triggeredAt": "2024-01-15T10:30:00.000Z",
"customer": {
"email": "customer@example.com",
"name": "John Doe",
"shopifyCustomerId": "gid://shopify/Customer/123456"
},
"id": "activity_xyz789",
"type": "demote_tier",
"oldTierId": "tier_gold_789",
"oldTierName": "Gold",
"newTierId": "tier_silver_456",
"newTierName": "Silver",
"tierPoint": 800,
"reason": "reassessment",
"createdAt": "2024-01-15T10:30:00.000Z"
}Referral events
referral/link_created
{
"webhookId": "referral_link_customer123_1705312200000",
"triggeredAt": "2024-01-15T10:30:00.000Z",
"customer": {
"email": "customer@example.com",
"name": "John Doe",
"shopifyCustomerId": "gid://shopify/Customer/123456"
},
"id": "referral_link_customer123_1705312200000",
"type": "referral_link_created",
"referralCode": "abc123xyz",
"urlReferral": "https://myshop.myshopify.com?ref=abc123xyz",
"createdAt": "2024-01-15T10:30:00.000Z"
}referral/reward_earned
{
"webhookId": "referral_reward_customer123_1705312200000",
"triggeredAt": "2024-01-15T10:30:00.000Z",
"customer": {
"email": "referrer@example.com",
"name": "John Doe",
"shopifyCustomerId": "gid://shopify/Customer/123456"
},
"id": "referral_reward_customer123_1705312200000",
"type": "referral_reward_earned",
"referredCustomerEmail": "referee@example.com",
"rewardType": "point",
"earnPoints": 500,
"couponCode": null,
"orderId": "gid://shopify/Order/789",
"createdAt": "2024-01-15T10:30:00.000Z"
}Birthday events
birthday/reward_earned
Points reward example:
{
"webhookId": "birthday_reward_customer123_1705312200000",
"triggeredAt": "2024-01-15T10:30:00.000Z",
"customer": {
"email": "customer@example.com",
"name": "John Doe",
"shopifyCustomerId": "gid://shopify/Customer/123456"
},
"id": "birthday_reward_customer123_1705312200000",
"type": "earn_point",
"event": "birthday",
"source": "user",
"earnPoints": 100,
"oldPoint": 500,
"newPoint": 600,
"createdAt": "2024-01-15T10:30:00.000Z"
}Discount reward example:
{
"webhookId": "5QIhElOglJOCfyX6Zo6I",
"triggeredAt": "2026-02-06T09:16:33.341Z",
"customer": {
"email": "customer@example.com",
"name": "John Doe",
"shopifyCustomerId": 9127686570181
},
"id": "5QIhElOglJOCfyX6Zo6I",
"source": "user",
"event": "birthday",
"type": "earn_DISCOUNT",
"createdAt": "2026-02-06T09:16:33.341Z"
}Milestone events
milestone/achieved
{
"webhookId": "activity_xyz789",
"triggeredAt": "2024-01-15T10:30:00.000Z",
"customer": {
"email": "customer@example.com",
"name": "John Doe",
"shopifyCustomerId": "gid://shopify/Customer/123456"
},
"id": "activity_xyz789",
"type": "earn_point",
"event": "milestone",
"earnBy": "order_count",
"oldPoint": 1000,
"newPoint": 1100,
"programTitle": "Order Milestone Rewards",
"createdAt": "2024-01-15T10:30:00.000Z"
}