> ## Documentation Index
> Fetch the complete documentation index at: https://developers.mageloyalty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Purchase a reward

> Redeem a reward for a customer, deducting points and generating a discount code.

Purchase a reward on behalf of a customer, deducting the required points from their balance and generating a Shopify discount code.

## Request body

| Field                 | Type    | Required             | Description                                                                                                                                                                      |
| --------------------- | ------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `customer_identifier` | string  | Yes                  | Shopify customer ID or email address                                                                                                                                             |
| `points`              | integer | For flexible rewards | How many points to spend. Used only by flexible rewards, where the customer chooses the amount. Must fall within the reward's allowed range. Also accepted as `points_to_redeem` |

```json theme={null}
{
  "customer_identifier": "6789012345"
}
```

<Note>
  Most rewards have a fixed `points_cost`, so the request only needs `customer_identifier`. For flexible rewards (`redemption_mode: "flexible"`), the customer chooses how many points to spend within the reward's allowed range, and the discount is sized to match. Pass `points` for these:

  ```json theme={null}
  {
    "customer_identifier": "6789012345",
    "points": 250
  }
  ```
</Note>

## Validations

* Customer must exist and not be excluded from the loyalty program
* Reward must be active and not deleted
* If the reward is restricted to a VIP tier, the customer must be on that tier
* Customer must have enough points to cover the reward's `points_cost`
* For flexible rewards, `points` is required and must be between the reward's configured minimum and maximum

## Response

Returns `201 Created`. The `discount_code` is the generated Shopify discount code for the customer to use, and `expires_at` is when that code stops working (`null` when the reward has no expiry configured). For flexible rewards, `reward_name` reflects the resolved discount (for example `$2.50 off your order`) and `points_spent` is the number of points the customer chose.

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.mageloyalty.com/v1/rewards/reward_abc/purchase \
    --header 'Authorization: <api-key>' \
    --header 'Content-Type: application/json' \
    --data '{
    "customer_identifier": "6789012345"
  }'
  ```

  ```javascript Node theme={null}
  const response = await fetch(
    "https://api.mageloyalty.com/v1/rewards/reward_abc/purchase",
    {
      method: "POST",
      headers: {
        Authorization: "<api-key>",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        customer_identifier: "6789012345",
      }),
    }
  );

  const data = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.mageloyalty.com/v1/rewards/reward_abc/purchase",
      headers={"Authorization": "<api-key>"},
      json={"customer_identifier": "6789012345"},
  )

  data = response.json()
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init("https://api.mageloyalty.com/v1/rewards/reward_abc/purchase");
  curl_setopt_array($ch, [
      CURLOPT_POST => true,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
          "Authorization: <api-key>",
          "Content-Type: application/json",
      ],
      CURLOPT_POSTFIELDS => json_encode([
          "customer_identifier" => "6789012345",
      ]),
  ]);
  $data = json_decode(curl_exec($ch), true);
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "data": {
      "type": "reward_history_entry",
      "id": "cr_abc123",
      "attributes": {
        "reward_id": "reward_abc",
        "reward_name": "£5 off your next order",
        "reward_discount_type": "fixed",
        "points_spent": 500,
        "discount_code": "MAGE-XYZ789",
        "status": "active",
        "expires_at": "2024-07-01T00:00:00.000Z"
      }
    }
  }
  ```

  ```json 400 Bad Request theme={null}
  {
    "errors": [
      {
        "status": "400",
        "title": "Bad Request",
        "detail": "Entry rewards cannot be purchased"
      }
    ]
  }
  ```

  ```json 403 Not Eligible theme={null}
  {
    "errors": [
      {
        "status": "403",
        "title": "Forbidden",
        "detail": "Customer is not eligible for this reward"
      }
    ]
  }
  ```

  ```json 404 Not Found theme={null}
  {
    "errors": [
      {
        "status": "404",
        "title": "Not Found",
        "detail": "Customer '6789012345' not found"
      }
    ]
  }
  ```

  ```json 422 Insufficient Points theme={null}
  {
    "errors": [
      {
        "status": "422",
        "title": "Insufficient Points",
        "detail": "Customer has 200 points but this reward costs 500"
      }
    ]
  }
  ```

  ```json 422 Invalid Points (flexible) theme={null}
  {
    "errors": [
      {
        "status": "422",
        "title": "Invalid Points",
        "detail": "Minimum redemption is 100 points"
      }
    ]
  }
  ```

  ```json 500 Internal Server Error theme={null}
  {
    "errors": [
      {
        "status": "500",
        "title": "Internal Server Error",
        "detail": "Failed to create discount code. Points have not been deducted."
      }
    ]
  }
  ```
</ResponseExample>

## Errors

| Status | Scenario                                                                                                                                                                                                       |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | `customer_identifier` missing, invalid JSON, the reward is an entry reward (`Entry rewards cannot be purchased`), or `points` is missing for a flexible reward (`points is required for flexible rewards`)     |
| `403`  | Customer is excluded from the loyalty program, or not on the required VIP tier (`Customer is not eligible for this reward`)                                                                                    |
| `404`  | Customer or reward not found                                                                                                                                                                                   |
| `422`  | Customer does not have enough points (`Customer has X points but this reward costs Y`), or `points` is outside a flexible reward's range (`Minimum redemption is X points` / `Maximum redemption is X points`) |
| `500`  | The discount code could not be generated. The points are refunded (`Failed to create discount code. Points have not been deducted.`)                                                                           |
| `503`  | Unable to connect to Shopify to generate the discount code                                                                                                                                                     |
