Learn how to use the Square Loyalty API to accumulate or adjust points for a loyalty account.
Loyalty API

Manage Loyalty Points

Buyers can earn loyalty points from qualified purchases and redeem points for reward discounts. The balance field of a loyalty account represents the number of points that can be used to create and redeem a reward.

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

Note

To get the available point balance for a loyalty account, call RetrieveLoyaltyAccount or SearchLoyaltyAccounts and check the balance field.

Call AccumulateLoyaltyPoints to add points earned from a purchase to a loyalty account. The information you provide in the request depends on whether your application uses the Orders API to process orders.


The accrual rules of a loyalty program determine whether a purchase qualifies for program points. Purchases that qualify for points from the base loyalty program might also qualify for points from a loyalty promotion.

If your application uses the Orders API to process orders, provide the following information in the AccumulateLoyaltyPoints request:

  • account_id with the ID of the target loyalty account. To get the account ID, call SearchLoyaltyAccounts and search using a phone number or customer ID.

  • accumulate_points with an order_id field that specifies the ID of the associated order. The order must be in the COMPLETED state. Square reads the order and computes the number of program points and promotion points earned from the purchase.

  • location_id with the ID of the location where the purchase was made. You can get this ID from the order.

  • idempotency_key with a unique identifier for this request, which is used to ensure idempotency.

Accumulate Loyalty Points
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
curl https://connect.squareupsandbox.com/v2/loyalty/accounts/{{ACCOUNT_ID}}/accumulate \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "accumulate_points": {
      "order_id": "cb9LSpDgOH3rITBaZ6eIBb9ee4F"
    },
    "location_id": "S8GWD509MEHCA",
    "idempotency_key": "{UNIQUE_KEY}"
  }'

For purchases that qualify for multiple accrual rules, Square computes points based on the accrual rule that grants the most points. For purchases that qualify for multiple promotions, Square computes points based on the most recently created promotion. A purchase must first qualify for program points to be eligible for promotion points.

Note

To see a typical application flow for adding earned points to a loyalty account, see Accumulate Loyalty Points for a Buyer.

When the purchase qualifies for points, Square returns loyalty events that represent the changes to the point balance. Square generates a searchable event each time the balance changes.

  • If program points are added, the response contains an ACCUMULATE_POINTS event.

  • If promotion points are added, the response also contains an ACCUMULATE_PROMOTION_POINTS event.

The following example response contains an ACCUMULATE_POINTS event. This single event indicates that the purchase only qualifies for program points.

The following example response contains an ACCUMULATE_POINTS event and ACCUMULATE_PROMOTION_POINTS event.

  • 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
{
  "events": [
    {
      "id": "bbd1ef00-92ac-3e5f-8887-cd3c6ba29313",
      "type": "ACCUMULATE_POINTS",
      "created_at": "2022-09-07T22:31:48Z",
      "accumulate_points": {
        "loyalty_program_id": "8031c1b2-d749-4c76-9c40-ae5472ed2e04",
        "points": 12,
        "order_id": "cb9LSpDgOH3rITBaZ6eIBb9ee4F"
      },
      "loyalty_account_id": "716cefbc-3d71-4d7c-bdc8-9c7f84c2d793",
      "location_id": "S8GWD509MEHCA",
      "source": "LOYALTY_API"
    },
    {
      "id": "b525f003-47ea-43aa-bb18-6d12cde50637",
      "type": "ACCUMULATE_PROMOTION_POINTS",
      "created_at": "2022-09-07T22:31:51Z",
      "accumulate_points": {
        "loyalty_program_id": "8031c1b2-d749-4c76-9c40-ae5472ed2e04",
        "points": 5,
        "order_id": "cb9LSpDgOH3rITBaZ6eIBb9ee4F"
      },
      "loyalty_account_id": "716cefbc-3d71-4d7c-bdc8-9c7f84c2d793",
      "location_id": "S8GWD509MEHCA",
      "source": "LOYALTY_API"
    }
  ]
}

If the purchase does not qualify for points, Square returns an empty object.

If your application uses a custom ordering system to process orders (instead of the Orders API), provide the following information in the AccumulateLoyaltyPoints request:

  • account_id with the ID of the target loyalty account. To get the account ID, call SearchLoyaltyAccounts and search using a phone number or customer ID.

  • accumulate_points with a points field that specifies the number of program points and promotion points to add to the account. You must first use client-side logic to compute the number of points earned from the purchase. For more information, see Computing points earned from a purchase.

  • location_id with the ID of the location where the purchase was made.

  • idempotency_key with a unique identifier for this request, which is used to ensure idempotency.

Accumulate Loyalty Points
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
curl https://connect.squareupsandbox.com/v2/loyalty/accounts/{{ACCOUNT_ID}}/accumulate \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "accumulate_points": {
      "points": 7
    },
    "location_id": "S8GWD509MEHCA",
    "idempotency_key": "{UNIQUE_KEY}"
  }'

Square returns an ACCUMULATE_POINTS loyalty event that represents the change to the point balance. Square generates a searchable event each time the balance changes.

The following is an example response:

For applications that do not use the Orders API to process orders, the events field contains a single ACCUMULATE_POINTS event. The ACCUMULATE_PROMOTION_POINTS event type is returned only when using Orders API integration.

Applications that use a custom ordering system can use the following process to compute the points earned from a purchase:

  1. Call RetrieveLoyaltyProgram using the main keyword (or the loyalty program ID, which is specified in the loyalty account).

  2. Check the accrual_rules field in the response. Each accrual rule defines the program type (SPEND, VISIT, CATALOG, or ITEM_VARIATION) in the accrual_type field, along with additional data that specifies the conditions for earning points from the base loyalty program. For purchases that qualify for multiple accrual rules, use the accrual rule that grants the most points.

    Note

    For SPEND program types and VISIT program types with a minimum spend requirement, you can call CalculateLoyaltyPoints and provide the purchase amount to get the number of program points the purchase qualifies for. Make sure to check the visit_data.tax_mode or spend_data.tax_mode field in the accrual rule to determine whether tax should be included in the purchase amount.

  3. If the purchase qualifies for program points, check whether it also qualifies for points from an associated loyalty promotion. For purchases that qualify for multiple promotions, use the most recently created promotion. For more information, see Calculating promotion points.

  4. Provide the combined program points and promotion points earned from the purchase in the points field of the AccumulateLoyaltyPoints request.

Call AdjustLoyaltyPoints to add or remove points from a loyalty account. You should use this endpoint only to add or remove points outside of the normal order-purchase flow. For example, use this endpoint to give extra points for a special offer or deduct points for a returned item.

Provide the following information in the request:

  • account_id with the ID of the target loyalty account. To get the account ID, call SearchLoyaltyAccounts and search using a phone number or customer ID.

  • adjust_points with a points field that specifies the number of points to add or remove and an optional reason field.

    • To add points, specify a positive integer.

    • To remove points, specify a negative integer. By default, Square does not accept a value that would result in a negative point balance. To allow a negative balance when subtracting points (for example, as a result of a refund or exchange), include the allow_negative_balance field in the request and set the value to true.

  • idempotency_key with a unique identifier for this request, which is used to ensure idempotency.

The following example request adds 15 points to a specified loyalty account:

Adjust Loyalty Points
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
curl https://connect.squareupsandbox.com/v2/loyalty/accounts/{{ACCOUNT_ID}}/adjust \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "adjust_points": {
      "points": 15,
      "reason": "Sign up bonus."
    },
    "idempotency_key": "{UNIQUE_KEY}"
  }'

Square returns an ADJUST_POINTS loyalty event that represents the change to the point balance. Square generates a searchable event each time the balance changes.

The following is an example response:

The following example request subtracts 6 points from the balance and sets allow_negative_balance to true:

Adjust Loyalty Points
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
curl https://connect.squareupsandbox.com/v2/loyalty/accounts/{{ACCOUNT_ID}}/adjust \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "adjust_points": {
      "points": -6,
      "reason": "Returned item"
    },
    "allow_negative_balance": true,
    "idempotency_key": "{UNIQUE_KEY}"
  }'

The following is an example response:

If allow_negative_balance is omitted from the request or set to false, Square returns a 400 BAD_REQUEST error if the operation would result in a negative point balance.

Call CalculateLoyaltyPoints to compute the number of points a purchase qualifies for. You can use this endpoint if you want to display the points while the buyer is building an order.

The information you provide in the request depends on whether your application uses the Orders API to process orders.


For purchases that qualify for multiple accrual rules, Square computes points based on the accrual rule that grants the most points. For purchases that qualify for multiple promotions, Square computes points based on the most recently created promotion. A purchase must first qualify for program points to be eligible for promotion points.

If your application uses the Orders API to process orders, provide the following information in the CalculateLoyaltyPoints request:

  • program_id with the ID of the loyalty program. To get this ID, call RetrieveLoyaltyProgram using the main keyword.

  • order_id with the ID of the associated order. Square reads the order and automatically computes the number of program points the purchase qualifies for.

  • loyalty_account_id with the ID of the loyalty account.

    • Specify this field to get the promotion points the buyer would earn from the purchase, based on whether the promotion's trigger_limit (the maximum number of times that a buyer can trigger the promotion) has been reached.

    • Omit this field to get the promotion points the purchase qualifies for regardless of the trigger limit.

Calculate Loyalty Points
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
curl https://connect.squareupsandbox.com/v2/loyalty/programs/{{PROGRAM_ID}}/calculate \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "order_id": "RFZfrdtm3mhO1oGzf5Cx7fEMsmGZY",
    "loyalty_account_id": "79b807d2-d786-46a9-933b-918028d7a8c5"
  }'

The following example response shows that the purchase qualifies for 6 program points. The 0 value for promotion_points means the purchase did not meet the conditions of a loyalty promotion or the buyer already reached the trigger limit.

The following example response shows that the purchase qualifies for 6 program points and 12 promotion points:

The following example response shows that the purchase does not qualify for program points or promotion points:

If your application uses a custom ordering system to process orders (instead of the Orders API), provide the following information in the CalculateLoyaltyPoints request:

  • program_id with the ID of the loyalty program. To get this ID, call RetrieveLoyaltyProgram using the main keyword.

  • transaction_amount_money with the purchase amount.

Calculate Loyalty Points
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
curl https://connect.squareupsandbox.com/v2/loyalty/programs/{{PROGRAM_ID}}/calculate \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "transaction_amount_money": {
      "amount": 1999,
      "currency": "USD"
    }
  }'

Applications that use a custom ordering system should be aware of the following considerations:

  • Because you must specify a purchase amount, this endpoint only supports SPEND program types or VISIT program types with a minimum spend requirement.

  • You must first check the tax mode to determine whether taxes should be included in the purchase amount. To find the tax mode setting for the loyalty program, check the visit_data.tax_mode field or spend_data.tax_mode field of any accrual rule listed in the accrual_rules field of the loyalty program.

  • If the purchase qualifies for program points, you must check whether it also qualifies for promotion points. For purchases that qualify for multiple promotions, use the most recently created promotion. For more information, see Calculating promotion points.

The following example response shows that the purchase qualifies for 3 program points based on the specified purchase amount:

The following example response shows that the purchase does not qualify for program points:

If a seller configures an expiration policy for a loyalty program, loyalty accounts that have a point balance include the expiring_point_deadlines field. This field contains a list of LoyaltyAccountExpiringPointDeadline objects that represent sets of points scheduled to expire at a specific time. For example, see the following:

  • 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_account":{
    "id":"716cefbc-3d71-4d7c-bdc8-9c7f84c2d793",
    "mapping": {
      "id":"6377d589-3f09-4f00-a0e8-56d7dfc1d2b5",
      "phone_number":"+16295551234",
      "created_at":"2020-01-30T00:11:58Z"
    },
    "program_id":"8031c1b2-d749-4c76-9c40-ae5472ed2e04",
    "balance":17,
    "lifetime_points":84,
    "customer_id":"REK96J96AS5AN2Y8Z4HE2Z5NVX",
    "created_at":"2020-01-30T00:11:58Z",
    "updated_at":"2021-07-15T09:33:45ZZ",
    "enrolled_at": "2020-01-30T00:11:58Z",
    "expiring_point_deadlines":[
      {
        "points":12,
        "expires_at":"2021-11-01T09:59:00Z"
      },
      {
        "points":5,
        "expires_at":"2022-08-01T09:59:00Z"
      }
    ]
  }
}

The total number of points in the expiring_point_deadlines field equals the number of points in the balance field.

Square notifies buyers 14 days before points expire. You can use expiration information to display expiring points in your application or send custom notifications.

When loyalty points are redeemed, Square uses the points with the earliest expiration date. When points expire, Square updates the account's point balance and creates a searchable loyalty event. These actions trigger the loyalty.account.updated and loyalty.event.created webhook events.

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