Learn about the LoyaltyPromotion object and how to use the Square Loyalty API to manage loyalty promotions.
Loyalty API

Manage Loyalty Promotions

Loyalty promotions can provide incentives for customers to change their buying behavior to earn extra loyalty points. For example, customers might be willing to try new products and services or make purchases at certain times of day. Promotions offer point-based incentives (for example, earn double points or earn five additional points) and can be scheduled to run indefinitely or at certain times.

The Loyalty API supports the following operations for working with loyalty promotions:

A loyalty promotion extends the base loyalty program. Buyers earn promotion points only if the purchase meets both the conditions of an accrual rule in the base loyalty program and the conditions of the loyalty promotion. A purchase can earn points for only one promotion. If a purchase qualifies for multiple promotions, Square selects the most recently created promotion.

If your application uses the Orders API to process orders, Square provides built-in integration for managing the points buyers earn from loyalty promotions. For more information, see Considerations.

The following example promotion gives buyers double points every Tuesday from 4 PM to 6 PM:

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
{
  "loyalty_promotion": {
    "id": "loypromo_f0f9b849-725e-378d-b810-511237e07b67",
    "name": "Tuesday Happy Hour",
    "incentive": {
      "type": "POINTS_MULTIPLIER",
      "points_multiplier_data": {
        "points_multiplier": 2
      }
    },
    "available_time": {
      "start_date": "2022-08-16",
      "time_periods": [
        "BEGIN:VEVENT\nDTSTART:20220816T160000\nDURATION:PT2H\nRRULE:FREQ=WEEKLY;BYDAY=TU\nEND:VEVENT"
      ]
    },
    "trigger_limit": {
      "times": 1,
      "interval": "DAY"
    },
    "status": "ACTIVE",
    "created_at": "2022-08-16T08:38:54Z",
    "updated_at": "2022-08-16T08:38:54Z",
    "loyalty_program_id": "d619f755-2d17-41f3-990d-c04ecedd64dd"
  }
}

The following table describes key loyalty promotions settings. For information about all available settings, see LoyaltyPromotion.

Field
Description
incentiveThe points incentive for the promotion, which specifies the POINTS_MULTIPLIER incentive type and points_multiplier value or the POINTS_ADDITION incentive type and points_addition value.
available_timeThe scheduling information that defines when purchases can qualify to earn promotion points. Square sets the start_date and (optional) end_date according to the time_periods event entries. For more information, see Available time.
trigger_limitThe number of times a buyer can trigger the promotion to earn points during a set interval (for example, three times per day). If not specified, buyers can trigger the promotion an unlimited number of times.
minimum_spend_amount_moneyThe minimum purchase amount required to earn promotion points. If not specified, the promotion has no minimum purchase requirement.
statusThe status of the promotion: ACTIVE, SCHEDULED, ENDED, or CANCELED. Buyers can earn promotion points only when the status is ACTIVE. Square sets the status according to the available_time.time_periods event information or when the promotion is canceled.
loyalty_program_idThe ID of the loyalty program associated with the promotion (also referred to as the base loyalty program).

When a loyalty promotion has an ACTIVE status, customers can earn promotion points for purchases that meet the conditions for both the base loyalty program and the loyalty promotion. Loyalty promotion conditions are determined by the following fields:

  • available_time

  • minimum_spend_amount_money

  • trigger_limit

The available_time field of a loyalty promotion defines when purchases can qualify to earn promotion points. The scheduling details are specified in the time_periods field using a list of iCalendar (RFC 5545) events (VEVENT). Each event represents an available time period per day or days of the week, which can be defined explicitly or implicitly. A day can have a maximum of one available time period.

The following VEVENT fields are supported:

  • DTSTART. Required. A timestamp of when the time period starts. The time portion must be in local (unzoned) time format. For example, DTSTART:20230101T090000.

  • DURATION. Required. The duration of the time period, relative to the DTSTART timestamp. For example, DURATION:PT3H30M represents 3 hours and 30 minutes.

  • RRULE. The recurrence rule for the time period. For example, RRULE:FREQ=WEEKLY;BYDAY=TH represents a recurrence on Thursdays. Only FREQ=WEEKLY is supported. To specify an end date, use the UNTIL keyword. To schedule a promotion to run 1 day only, omit the RRULE field.

After the promotion is created:

  • Square sets the start_date to the earliest date specified. When the start_date is reached, Square sets the status of the promotion to ACTIVE.

  • If end dates are specified, Square sets the end_date to the latest date specified. When the end_date is reached, Square sets the status to ENDED. Loyalty promotions that have no end date run until the promotion is canceled.

The event in the following example defines a promotion that starts August 17, 2022, and is available every Monday, Wednesday, and Friday from 5 PM to 7 PM:

The two events in the following example define a promotion that starts December 1, 2022, and is available every Monday from 10 AM to 3:30 PM and Thursday from 11 AM to 3 PM:

The event in the following example defines a promotion that starts October 1, 2022, and is available every Tuesday until October 31, 2023:

The event in the following example defines a promotion that is available only on September 5, 2022, from 9 AM to 9 PM:

Note that BEGIN:VEVENT and END:VEVENT are optional in a CreateLoyaltyPromotion request but are always included in the response.

To create a loyalty promotion, call CreateLoyaltyPromotion and provide the following information:

  • The program_id path parameter with the ID of the associated loyalty program. You can get the program ID from the loyalty promotion or by calling RetrieveLoyaltyProgram using the main keyword.

  • The loyalty_promotion field with the following fields:

    • incentive with the points incentive for the promotion:

      • To multiply the points earned from the base loyalty program, specify POINTS_MULTIPLIER for type and provide points_multiplier_data with the points_multiplier value. For example, to enable buyers to earn double points, set the value to 2.

      • To add points to the points earned from the base loyalty program, specify POINTS_ADDITION for type and provide points_addition_data with the points_addition value. For example, to enable buyers to earn 3 extra points, set the value to 3.

    • available_time with scheduling information specified as iCalendar events in the time_periods field. Square uses this event data to populate the start_date and (optional) end_at fields and to set the loyalty promotion to the ACTIVE or SCHEDULED status. For more information, see Available time.

    • trigger_limit with the times and interval fields that specify the number of times a buyer can trigger the promotion to earn points. If not specified, buyers can trigger the promotion an unlimited number of times.

    • minimum_spend_amount_money with the minimum purchase amount required to earn promotion points. If specified, this amount is positive. If not specified, the promotion has no minimum purchase.

The following example request specifies an incentive that gives double points. The available_time field specifies that buyers can earn promotion points every Tuesday from 4 PM to 6 PM. The trigger_limit field specifies that the promotion points can be earned a maximum of once per day (each Tuesday).

Create Loyalty Promotion
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
curl https://connect.squareupsandbox.com/v2/loyalty/programs/{program_id}/promotions \
  -X POST \
  -H 'Square-Version: 2022-09-21' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "loyalty_promotion": {
      "name": "Tuesday Happy Hour",
      "incentive": {
        "type": "POINTS_MULTIPLIER",
        "points_multiplier_data": {
          "points_multiplier": 2
        }
      },
      "available_time": {
        "time_periods": [
          "BEGIN:VEVENT\nDTSTART:20220816T160000\nDURATION:PT2H\nRRULE:FREQ=WEEKLY;UNTIL=20221001T000000;BYDAY=TU\nEND:VEVENT"
        ]
      },
      "trigger_limit": {
        "times": 1,
        "interval": "DAY"
      },
      "idempotency_key": "{UNIQUE_KEY}"
    }
  }'

The following is an example response:

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
{
  "loyalty_promotion": {
    "id": "19514729-2073-313d-81f1-dc0231660ef0",
    "name": "Tuesday Happy Hour",
    "incentive": {
      "type": "POINTS_MULTIPLIER",
      "points_multiplier_data": {
        "points_multiplier": 2
      }
    },
    "available_time": {
      "start_date": "2022-08-16",,
      "end_date": "2022-10-01",
      "time_periods": [
        "BEGIN:VEVENT\nDTSTART:20220816T160000\nDURATION:PT2H\nRRULE:FREQ=WEEKLY;UNTIL=20221001T000000;BYDAY=TU\nEND:VEVENT"
      ]
    },
    "trigger_limit": {
      "times": 1,
      "interval": "DAY"
    },
    "status": "ACTIVE",
    "created_at": "2022-08-16T08:38:54Z",
    "updated_at": "2022-08-16T08:38:54Z",
    "loyalty_program_id": "d619f755-2d17-41f3-990d-c04ecedd64dd"
  }
}

A loyalty program can have a maximum of 10 loyalty promotions with an ACTIVE and SCHEDULED status.

To retrieve a loyalty promotion, call RetrieveLoyaltyPromotion and provide the following information:

  • The promotion_id path parameter with the ID of the loyalty promotion to retrieve. To get the promotion ID, call ListLoyaltyPromotions.

  • The program_id path parameter with the ID of the associated loyalty program. To get the program ID, call RetrieveLoyaltyProgram using the main keyword.

Retrieve Loyalty Promotion
  • 1
  • 2
  • 3
  • 4
curl https://connect.squareupsandbox.com/v2/loyalty/programs/{program_id}/promotions/{promotion_id} \
  -H 'Square-Version: 2022-09-21' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json'

The following is an example response:

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
{
  "loyalty_promotion": {
    "id": "loypromo_f0f9b849-725e-378d-b810-511237e07b67",
    "name": "Tuesday Happy Hour",
    "incentive": {
      "type": "POINTS_MULTIPLIER",
      "points_multiplier_data": {
        "points_multiplier": 2
      }
    },
    "available_time": {
      "start_date": "2022-08-16",
      "time_periods": [
        "BEGIN:VEVENT\nDTSTART:20220816T160000\nDURATION:PT2H\nRRULE:FREQ=WEEKLY;BYDAY=TU\nEND:VEVENT"
      ]
    },
    "trigger_limit": {
      "times": 1,
      "interval": "DAY"
    },
    "status": "ACTIVE",
    "created_at": "2022-08-16T08:38:54Z",
    "updated_at": "2022-08-16T08:38:54Z",
    "loyalty_program_id": "d619f755-2d17-41f3-990d-c04ecedd64dd"
  }
}

To list the loyalty promotions associated with a loyalty program, call ListLoyaltyPromotions and provide the following information:

  • The program_id path parameter with the ID of the associated loyalty program. To get the program ID, call RetrieveLoyaltyProgram using the main keyword.

  • The optional status query parameter with the ACTIVE, SCHEDULED, ENDED, or CANCELED target status. By default, loyalty promotions are returned regardless of the promotion status.

  • The optional limit query parameter with a maximum page size of 1 to 30 results. The default limit is 30.

    If the results are paged, use the cursor field in the response as the cursor query parameter in your next ListLoyaltyPromotions request.

The following example request uses status to return only ACTIVE promotions and limit to specify a maximum page size of 2 results:

List Loyalty Promotions
  • 1
  • 2
  • 3
  • 4
curl https://connect.squareupsandbox.com/v2/loyalty/programs/{program_id}/promotions?status=ACTIVE&limit=2 \
  -H 'Square-Version: 2022-09-21' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json'

The following example response contains two loyalty promotions. Results are sorted by the created_at timestamp in descending order.

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
{
  "loyalty_promotions": [
    {
      "id": "loypromo_f0f9b849-725e-378d-b810-511237e07b67",
      "name": "Tuesday Happy Hour",
      "incentive": {
        "type": "POINTS_MULTIPLIER",
        "points_multiplier_data": {
          "points_multiplier": 2
        }
      },
      "available_time": {
        "start_date": "2022-08-16",
        "time_periods": [
          "BEGIN:VEVENT\nDTSTART:20220816T160000\nDURATION:PT2H\nRRULE:FREQ=WEEKLY;BYDAY=TU\nEND:VEVENT"
        ]
      },
      "trigger_limit": {
        "times": 1,
        "interval": "DAY"
      },
      "status": "ACTIVE",
      "created_at": "2022-08-16T08:38:54Z",
      "updated_at": "2022-08-16T08:38:54Z",
      "loyalty_program_id": "d619f755-2d17-41f3-990d-c04ecedd64dd"
    },
    {
      "id": "loypromo_e696f057-2286-35ff-8108-132241328106",
      "name": "July Special",
      "incentive": {
        "type": "POINTS_ADDITION",
        "points_addition_data": {
          "points_addition": 5
        }
      },
      "available_time": {
        "start_date": "2022-07-01",
        "end_date": "2022-08-01",
        "time_periods": [
          "BEGIN:VEVENT\nDTSTART:20220704T090000\nDURATION:PT8H\nRRULE:FREQ=WEEKLY;UNTIL=20220801T000000;BYDAY=MO\nEND:VEVENT",
          "BEGIN:VEVENT\nDTSTART:20220705T090000\nDURATION:PT8H\nRRULE:FREQ=WEEKLY;UNTIL=20220801T000000;BYDAY=TU\nEND:VEVENT",
          "BEGIN:VEVENT\nDTSTART:20220706T090000\nDURATION:PT8H\nRRULE:FREQ=WEEKLY;UNTIL=20220801T000000;BYDAY=WE\nEND:VEVENT",
          "BEGIN:VEVENT\nDTSTART:20220707T090000\nDURATION:PT8H\nRRULE:FREQ=WEEKLY;UNTIL=20220801T000000;BYDAY=TH\nEND:VEVENT",
          "BEGIN:VEVENT\nDTSTART:20220701T090000\nDURATION:PT8H\nRRULE:FREQ=WEEKLY;UNTIL=20220801T000000;BYDAY=FR\nEND:VEVENT"
        ]
      },
      "trigger_limit": {
        "times": 10,
        "interval": "ALL_TIME"
      },
      "minimum_spend_amount_money": {
        "amount": 2000,
        "currency": "USD"
      },
      "status": "ACTIVE",
      "created_at": "2022-06-27T15:37:38Z",
      "updated_at": "2022-06-27T15:37:38Z",
      "loyalty_program_id": "d619f755-2d17-41f3-990d-c04ecedd64dd"
    }
  ],
  "cursor": "PNEhVUKHBuTOuRIZoUcX5VQexample"
}

If no results are found, the response contains an empty object:

To cancel a loyalty promotion, call CancelLoyaltyPromotion. You can use this endpoint to cancel an ACTIVE promotion earlier than the end date, cancel an ACTIVE promotion when an end date is not specified, or cancel a SCHEDULED promotion. Because updating a promotion is not supported, you should also use this endpoint to cancel an ACTIVE or SCHEDULED promotion before you create a new one.

Provide the following information in the request:

  • The promotion_id path parameter with the ID of the loyalty promotion to cancel. To get the promotion ID, call ListLoyaltyPromotions.

  • The program_id path parameter with the ID of the associated loyalty program. You can get the program ID from the loyalty promotion or by calling RetrieveLoyaltyProgram using the main keyword.

Cancel Loyalty Promotion
  • 1
  • 2
  • 3
  • 4
  • 5
curl https://connect.squareupsandbox.com/v2/loyalty/programs/{program_id}/promotions/{promotion_id}/cancel \
  -X POST \
  -H 'Square-Version: 2022-09-21' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json'

Square sets the promotion status to CANCELED, which is a terminal state.

The following is an example response that contains the canceled promotion:

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
{
  "loyalty_promotion": {
    "id": "loypromo_f0f9b849-725e-378d-b810-511237e07b67",
    "name": "Tuesday Happy Hour",
    "incentive": {
      "type": "POINTS_MULTIPLIER",
      "points_multiplier_data": {
        "points_multiplier": 2
      }
    },
    "available_time": {
      "start_date": "2022-08-16",
      "time_periods": [
        "BEGIN:VEVENT\nDTSTART:20220816T160000\nDURATION:PT2H\nRRULE:FREQ=WEEKLY;BYDAY=TU\nEND:VEVENT"
      ]
    },
    "trigger_limit": {
      "times": 1,
      "interval": "DAY"
    },
    "status": "CANCELED",
    "created_at": "2022-08-16T08:38:54Z",
    "canceled_at": "2022-08-17T12:42:49Z",
    "updated_at": "2022-08-17T12:42:49Z",
    "loyalty_program_id": "d619f755-2d17-41f3-990d-c04ecedd64dd"
  }
}

Purchases that qualify for points from the base loyalty program might also qualify for points from a loyalty promotion.

Note

If your application uses the Orders API to process orders, Square provides built-in integration for managing the points that buyers earn from loyalty promotions. Square computes both program points and promotions points when you call AccumulateLoyaltyPoints or CalculateLoyaltyPoints and provide the ID of a Square order.

If a purchase qualifies for program points, use the following procedure to check whether a purchase also qualifies for promotion points:

  1. Call ListLoyaltyPromotions using the status query parameter to filter for the ACTIVE promotions associated with the loyalty program. Results are sorted in descending order by the created_at date.

  2. Starting with the most recently created promotion, check whether the purchase meets all the following conditions. If it does not, check the next ACTIVE promotion in descending order by the created_at date.

    • Available time. The purchase must occur during a time period specified in the available_time.time_periods field. This field contains a list of iCalendar events that define the day of the week and the time of day that a promotion is available. For more information, see Available time.

    • Minimum amount. If minimum_spend_amount_money is specified, the purchase amount must be greater than or equal to the specified amount. If needed, retrieve the loyalty program and check the tax_mode field of any accrual rule to determine whether taxes should be included in the purchase amount.

    • Trigger limit. If trigger_limit is specified, the buyer cannot exceed this limit. If not specified, the promotion can be triggered an unlimited number of times. Note that applications that use a custom ordering system must record each time a loyalty account triggers a promotion to determine whether the buyer has reached the promotion's trigger limit.

  3. If the purchase meets the promotion conditions, check the incentive field of the promotion to determine how to compute the promotion points:

    • If type is POINTS_MULTIPLIER, get the multiplier from the points_multiplier_data.points_multiplier field. For example, a purchase that qualifies for 5 program points with a points multiplier of 3 earns:

      • 5 program points.

      • 10 promotion points ((program points x multiplier) – program points).

      • 15 total points.

      For this example, applications that use a custom ordering system would provide a points value of 15 in an AccumulateLoyaltyPoints request and record that the loyalty account received 10 points from the loyalty promotion from the purchase.

    • If type is POINTS_ADDITION, get the number of promotions points to add from the points_addition_data.points_addition field. For example, a purchase that qualifies for 5 program points with a points addition of 3 earns:

      • 5 program points.

      • 3 promotion points.

      • 8 total points.

      For this example, applications that use a custom ordering system would provide a points value of 8 in an AccumulateLoyaltyPoints request and record that the loyalty account received 3 points from the loyalty promotion from the purchase.

    A purchase can earn points from one promotion only.

The following considerations apply when working with loyalty promotions:

  • Applications must use Square version 2022-08-17 or later to work with loyalty promotions.

  • For applications that use the Orders API to process orders, Square provides built-in integration for managing the points buyers earn from loyalty promotions. For example, when you call AccumulateLoyaltyPoints and provide the order_id, Square automatically adds the program points and promotion points to the loyalty account. Similarly, when you call CalculateLoyaltyPoints and provide the order_id, Square computes both program points and promotions points.

  • For applications that use a custom ordering system to process orders (instead of the Orders API), Square provides limited support for managing promotion points for buyers. For example, the CalculateLoyaltyPoints endpoint does not compute promotion points for these applications. In addition, the AccumulateLoyaltyPoints endpoint does not provide a parameter to specify promotion points earned from a purchase, and therefore returns only ACCUMULATE_POINTS events (not ACCUMULATE_PROMOTION_POINTS events).

    These applications must compute promotion points for qualifying purchases and keep track of the promotion points added to each loyalty account to be able to determine whether the buyer has reached the promotion's trigger limit. For more information, see Calculating promotion points.

  • A purchase can earn points for only one promotion. If a purchase qualifies for multiple promotions, Square selects the most recently created promotion that has an ACTIVE status. A purchase must qualify for points from the base loyalty program to be eligible for promotion points.

  • Loyalty promotions are available in all business locations for the Square seller and to all customers who are enrolled in the loyalty program.

  • Promotion points are subject to the same expiration policy as program points.

If you need more assistance, contact Developer Support or ask for help in the Developer Forums.