# API Reference

## Open in Postman

Easily test these API methods dynamically by using our Postman Collection.  Just change the `Token` in the Authorizations tab, and the `campaign_id` variable to the program you're working on.

[![Run in Postman](https://run.pstmn.io/button.svg)](https://www.postman.com/growsurf/growsurf-public/collection/xvgm0uy/loyaltysurf-rest-api)

***

## CAMPAIGNS ↓

### Get Campaign

<mark style="color:blue;">`GET`</mark> `https://api.loyaltysurf.io/v1/campaign/:id`

Retrieves a program for the given program ID.

#### Path Parameters

| Name                                 | Type   | Description                       |
| ------------------------------------ | ------ | --------------------------------- |
| id<mark style="color:red;">\*</mark> | string | The ID of the program to retrieve |

#### Response

{% tabs %}
{% tab title="200" %}
Returns the program.

```json
{
    "id": "abc123",
    "name": "Pied Piper Advocate Program",
    "loyaltyActionCount": 121,
    "participantCount": 199,
    "winnerCount": 1,
    "status": "IN_PROGRESS",
    "currencyISO": "USD",
    "rewards": [
        {
            "id": "crew_xyz789",
            "description": "Make a LinkedIn post mentioning Pied Piper",
            "subdescription": "Post must be less than 1 week old from date of submission",
            "instructions": "<div><p><strong>Helpful tips:</strong></p><ul><li>Talk about how you used to do things before using Pied Piper</li><li>Mention specific ROIs (e.g, time saved, revenue generated)</li></ul></div>",
            "cta": "Get $25",
            "submissionType": "URL",
            "submissionExampleUrl": "https://linkedin.com/posts/sarah_s-my-review-of-pied-piper-8195769799870726145-Sr9b",
            "submissionFormUrl": "https://linkedin.com/shareArticle",
            "submissionFormFields": [
                {
                    "key": "linkedinPostUrl",
                    "label": "Your LinkedIn Post URL",
                    "placeholder": "Enter your LinkedIn Post URL here",
                    "type": "text",
                    "isRequired": true,
                    "isVisible": true
                }
            ],
            "submissionFormButtonText": "Submit",
            "submissionFormMessages": {
                "required": "is required",
                "reCaptchaRequired": "You must pass the reCAPTCHA verification.",
                "success": "Thanks! We have received your response.",
                "error": "There was an error. Please try submitting again.",
                "alreadySubmitted": "You already submitted this form."
            },
            "isUnlimited": false,
            "limit": 1,
            "conversionsRequired": 1,
            "imageUrl": "http://res.cloudinary.com/loyaltysurf/image/upload/v1552764861/development/hxdcjrayfhksvxu5u6oz.png"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

### Get Campaigns

<mark style="color:blue;">`GET`</mark> `https://api.loyaltysurf.io/v1/campaigns`

Retrieves a list of your programs. Programs that have been deleted will not be returned in this response.

#### Response

{% tabs %}
{% tab title="200" %}
Returns the programs.

```json
{
    "campaigns": [
        {
            "id": "abc123",
            "name": "Pied Piper Advocate Program",
            "loyaltyActionCount": 20500,
            "participantCount": 40000,
            "winnerCount": 1500,
            "status": "IN_PROGRESS",
            "currencyISO": "USD",
            "rewards": [
                {
                    "id": "crew_xyz789",
                    "description": "Make a LinkedIn post mentioning Pied Piper",
                    "subdescription": "Post must be less than 1 week old from date of submission",
                    "instructions": "<div><p><strong>Helpful tips:</strong></p><ul><li>Talk about how you used to do things before using Pied Piper</li><li>Mention specific ROIs (e.g, time saved, revenue generated)</li></ul></div>",
                    "cta": "Get $25",
                    "submissionType": "URL",
                    "submissionExampleUrl": "https://linkedin.com/posts/sarah_s-my-review-of-pied-piper-8195769799870726145-Sr9b",
                    "submissionFormUrl": "https://linkedin.com/shareArticle",
                    "submissionFormFields": [
                        {
                            "key": "linkedinPostUrl",
                            "label": "Your LinkedIn Post URL",
                            "placeholder": "Enter your LinkedIn Post URL here",
                            "type": "text",
                            "isRequired": true,
                            "isVisible": true
                        }
                    ],
                    "submissionFormButtonText": "Submit",
                    "submissionFormMessages": {
                        "required": "is required",
                        "reCaptchaRequired": "You must pass the reCAPTCHA verification.",
                        "success": "Thanks! We have received your response.",
                        "error": "There was an error. Please try submitting again.",
                        "alreadySubmitted": "You already submitted this form."
                    },
                    "isUnlimited": false,
                    "limit": 1,
                    "conversionsRequired": 1,
                    "imageUrl": "http://res.cloudinary.com/loyaltysurf/image/upload/v1552764861/development/hxdcjrayfhksvxu5u6oz.png"
                }
            ]
        },
        {
            "id": "ljtqn5",
            "name": "Pied Piper Advocate Program #2",
            "loyaltyActionCount": 30500,
            "participantCount": 60000,
            "winnerCount": 750,
            "status": "IN_PROGRESS",
            "currencyISO": "USD",
            "rewards": [
                {
                    "id": "crew_qiar1r",
                    "description": "Make an X (Twitter) post about Pied Piper",
                    "subdescription": "Post must be less than 1 week old from date of submission",
                    "instructions": "<div><p><strong>Helpful tips:</strong></p><ul><li>Talk about how you used to do things before using Pied Piper</li><li>Mention specific ROIs (e.g, time saved, revenue generated)</li></ul></div>",
                    "cta": "Get $15",
                    "submissionType": "URL",
                    "submissionExampleUrl": "https://x.com/Sarah_S/status/2307836134014308344",
                    "submissionFormUrl": "https://x.com/compose/post",
                    "submissionFormFields": [
                        {
                            "key": "twitterPostUrl",
                            "label": "Your Twitter Post URL",
                            "placeholder": "Enter your Twitter Post URL here",
                            "isRequired": true,
                            "isVisible": true
                        }
                    ],
                    "submissionFormButtonText": "Submit",
                    "submissionFormMessages": {
                        "required": "is required",
                        "reCaptchaRequired": "You must pass the reCAPTCHA verification.",
                        "success": "Thanks! We have received your response.",
                        "error": "There was an error. Please try submitting again.",
                        "alreadySubmitted": "You already submitted this form."
                    },
                    "isUnlimited": false,
                    "limit": 1,
                    "conversionsRequired": 1,
                    "imageUrl": "http://res.cloudinary.com/loyaltysurf/image/upload/v1552764861/development/hxdcjrayfhksvxu5u6oz.png"
                }
            ]
        }
    ]
}
```

{% endtab %}
{% endtabs %}

***

***

## LOYALTY ACTIONS ↓

### Trigger Loyalty Action by Email

<mark style="color:green;">`POST`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/loyalty-action`

Triggers a loyalty action for a person, awarding loyalty action credit to them and adds them to the program as a participant if they do not already exist.

If the required number of loyalty actions of the program reward is reached, then the reward will be unlocked.

#### Path Parameters

| Name                                 | Type   | Description           |
| ------------------------------------ | ------ | --------------------- |
| id<mark style="color:red;">\*</mark> | string | The ID of the program |

#### Request Body

| Name                                               | Type    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| -------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| participantEmail<mark style="color:red;">\*</mark> | string  | The email address of the person that performed the loyalty action. If the person already exists as a participant, then their loyalty action count will be incremented.                                                                                                                                                                                                                                                                                                 |
| rewardId<mark style="color:red;">\*</mark>         | string  | The program reward ID that the participant will earn upon completing the required number of loyalty actions.                                                                                                                                                                                                                                                                                                                                                           |
| addParticipantIfNoneExists                         | boolean | Adds the person to the program as a participant if they do not already exist. Defaults to `true`.                                                                                                                                                                                                                                                                                                                                                                      |
| firstName                                          | string  | <p>(Applies only if <code>addParticipantIfNoneExists</code> is <code>true</code>. Optional, but recommended)</p><p><br>The first name of the new participant. If provided, this property will be used for anti-fraud measurements.</p>                                                                                                                                                                                                                                 |
| lastName                                           | string  | <p>(Applies only if <code>addParticipantIfNoneExists</code> is <code>true</code>. Optional, but recommended)<br><br>The last name of the new participant. If provided, this property will be used for anti-fraud measurements.</p>                                                                                                                                                                                                                                     |
| ipAddress                                          | string  | <p>(Applies only if <code>addParticipantIfNoneExists</code> is <code>true</code>. Optional, but recommended)<br><br>The IP address of the new participant. If provided, this property will be used for anti-fraud measurements.</p>                                                                                                                                                                                                                                    |
| fingerprint                                        | string  | <p>(Applies only if <code>addParticipantIfNoneExists</code> is <code>true</code>. Optional, but recommended)<br><br>The browser fingerprint of the new participant. If provided, this property will be used for anti-fraud measurements.<br><br>We recommend using a front-end library like <a href="https://github.com/fingerprintjs/fingerprintjs">fingerprintjs</a> to get the fingerprint value. Example value: <code>cfb163bd47ba666c52cb932c521e47f4</code>.</p> |
| metadata                                           | object  | <p>(Applies only if <code>addParticipantIfNoneExists</code> is <code>true</code>. Optional)<br><br>A shallow Object containing custom key/values to include with the participant data.</p>                                                                                                                                                                                                                                                                             |

#### Response

{% tabs %}
{% tab title="200" %}
Returns an object with a `success` attribute equal to `true` if the loyalty action was triggered, otherwise `false`.

The response also contains the updated participant \[who just performed the loyalty action] or the newly-created participant if `addParticipantIfNoneExists` was specified.

```json
{
  "success": true,
  "message": "Successfully awarded loyalty reward.",
  "participant": {
    "id": "cq3e6a",
    "campaignId": "abc123",
    "email": "foobaekrkerj@gmail.com",
    "firstName": "Foo",
    "lastName": "Bar",
    "createdAt": 1671008290019,
    "updatedAt": 1671008290407,
    "loyaltyActionCount": 1,
    "monthlyLoyaltyActionCount": 1,
    "prevMonthlyLoyaltyActionCount": 0,
    "prevLoyaltyActionCount": 0,
    "loyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "monthlyLoyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "loyaltyActionSource": "DIRECT",
    "fraudRiskLevel": "LOW",
    "fraudReasonCode": "UNIQUE_IDENTITY",
    "isWinner": false,
    "rank": -1,
    "monthlyRank": -1,
    "prevMonthlyRank": -1,
    "rewards": [],
    "reviewedRewardFormSubmissionCount": 0,
    "unreviewedRewardFormSubmissionCount": 0,
    "metadata": {},
    "unsubscribed": false
  }
}
```

{% endtab %}

{% tab title="400" %}
A `400` will be returned if validation fails on an input.

```javascript
{
  "name": "BadRequestError",
  "code": "BAD_REQUEST_ERROR",
  "message": "Invalid email foo",
  "errors": […],
  "status": 400,
  "supportUrl": "https://app.loyaltysurf.io/settings#contact_support"
}
```

{% endtab %}

{% tab title="409" %}
A `409` error will be returned if the request is a duplicate.

```javascript
{
  "name": "DuplicateRequestError",
  "code": "DUPLICATE_REQUEST_ERROR",
  "message": "Duplicate request is already in progress. Loyalty action credit is already being triggered for the participant.",
  "status": 409,
  "supportUrl": "https://app.loyaltysurf.io/settings#contact_support"
}
```

{% endtab %}

{% tab title="422" %}
If the new participant is detected to be a high-level fraudster, and if anti-fraud settings are configured on the campaign, the participant will be blocked from joining with a status code of `422`.\
\
View the list of available `fraudRiskLevel` and `fraudReasonCode` options on the [Participant](https://docs.loyaltysurf.io/developer-tools/rest-api/api-objects#participant) Object. `matchedParticipantIds` will contain a list of matching fraudsters, but will be empty if an antifraud blacklist rule gets a match first.

```javascript
{
  "name": "ParticipantBlockedError",
  "code": "PARTICIPANT_BLOCKED_ERROR",
  "message": "Participant sarah.smith@email.com is blocked by antifraud rules.",
  "status": 422,
  "supportUrl": "https://app.loyaltysurf.io/settings#contact_support",
  "fraudRiskLevel": "HIGH",
  "fraudReasonCode": "BLACKLIST_MATCH",
  "matchedParticipantIds": [],
  "email": "sarah.smith@email.com",
  "ipAddress": "203.0.113.10",
  "fingerprint": null,
  "blockedAt": "2025-11-13T06:22:31.001Z"
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Metadata:** Please see our [API Guidelines](https://docs.loyaltysurf.io/developer-tools/api-guidelines#metadata)[ ](https://docs.loyaltysurf.io/developer-tools/api-guidelines#metadata)for more information about `metadata.`
{% endhint %}

### Trigger Loyalty Action by Participant ID

<mark style="color:green;">`POST`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/loyalty-action`

Triggers a loyalty action for an existing participant.

If the required number of loyalty actions of the program reward is reached, then the reward will be unlocked.

#### Path Parameters

| Name                                 | Type   | Description           |
| ------------------------------------ | ------ | --------------------- |
| id<mark style="color:red;">\*</mark> | string | The ID of the program |

#### Request Body

| Name                                            | Type   | Description                                                                                                  |
| ----------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------ |
| participantId<mark style="color:red;">\*</mark> | string | The ID of the participant that performed the loyalty action.                                                 |
| rewardId<mark style="color:red;">\*</mark>      | String | The program reward ID that the participant will earn upon completing the required number of loyalty actions. |

#### Response

{% tabs %}
{% tab title="200" %}
Returns an object with a `success` attribute equal to `true` if the loyalty action was triggered, otherwise `false`.

The response also contains the updated participant \[who just performed the loyalty action].

```json
{
  "success": true,
  "message": "Successfully awarded loyalty reward.",
  "participant": {
    "id": "cq3e6a",
    "campaignId": "abc123",
    "email": "foobaekrkerj@gmail.com",
    "firstName": "Foo",
    "lastName": "Bar",
    "createdAt": 1671008290019,
    "updatedAt": 1671008290407,
    "loyaltyActionCount": 1,
    "monthlyLoyaltyActionCount": 1,
    "prevMonthlyLoyaltyActionCount": 0,
    "prevLoyaltyActionCount": 0,
    "loyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "monthlyLoyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "loyaltyActionSource": "DIRECT",
    "fraudRiskLevel": "LOW",
    "fraudReasonCode": "UNIQUE_IDENTITY",
    "isWinner": false,
    "rank": -1,
    "monthlyRank": -1,
    "prevMonthlyRank": -1,
    "rewards": [],
    "reviewedRewardFormSubmissionCount": 0,
    "unreviewedRewardFormSubmissionCount": 0,
    "metadata": {},
    "unsubscribed": false
  }
}
```

{% endtab %}

{% tab title="400" %}
A `400` will be returned if validation fails on an input.

```javascript
{
  "name": "BadRequestError",
  "code": "BAD_REQUEST_ERROR",
  "message": "Invalid email foo",
  "errors": […],
  "status": 400,
  "supportUrl": "https://app.loyaltysurf.io/settings#contact_support"
}
```

{% endtab %}

{% tab title="409" %}
A `409` error will be returned if the request is a duplicate.

```javascript
{
  "name": "DuplicateRequestError",
  "code": "DUPLICATE_REQUEST_ERROR",
  "message": "Duplicate request is already in progress. Loyalty action credit is already being triggered for the participant.",
  "status": 409,
  "supportUrl": "https://app.loyaltysurf.io/settings#contact_support"
}
```

{% endtab %}
{% endtabs %}

***

## PARTICIPANTS ↓

### Get Participant by ID

<mark style="color:blue;">`GET`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantId`

Retrieves a single participant from a program using the given participant ID.

#### Path Parameters

| Name                                            | Type   | Description                                            |
| ----------------------------------------------- | ------ | ------------------------------------------------------ |
| id<mark style="color:red;">\*</mark>            | string | The ID of the program to retrieve the participant from |
| participantId<mark style="color:red;">\*</mark> | string | The ID of the participant to retrieve                  |

#### Response

{% tabs %}
{% tab title="200" %}
Returns the participant object.

```json
{
    "id": "f8g9nl",
    "firstName": "Gavin",
    "lastName": "Belson",
    "loyaltyActionCount": 2,
    "monthlyloyaltyActionCount": 2,
    "prevMonthlyLoyaltyActionCount": 0,
    "rank": 10001,
    "monthlyRank": 20001,
    "monthlyRank": -1,
    "email": "gavin@hoolie.com",
    "createdAt": 1552404738928,
    "fraudRiskLevel": "LOW",
    "fraudReasonCode": "UNIQUE_IDENTIY",
    "isWinner": true,
    "loyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "monthlyLoyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "loyaltyActionSource": "DIRECT",
    "ipAddress": "127.0.0.1",
    "fingerprint": "cfb163bd47ba666c52cb932c521e47f4",
    "metadata": {
       "company": "Hooli, Inc",
       "companySize": 10000
    },
    "unsubscribed": false,
    "rewards": [
        {
            "id": "prew_9x8v1b",
            "rewardId": "crew_m5xm9l",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        },
        {
            "id": "prew_vsdj34",
            "rewardId": "crew_w01fil",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        },
        {
            "id": "prew_sj3kap",
            "rewardId": "crew_w01fil",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        }
    ]
}
```

{% endtab %}
{% endtabs %}

### Get Participant by Email

<mark style="color:blue;">`GET`</mark> `https://api.loyaltysurf.com/v1/campaign/:id/participant/:participantEmail`

Retrieves a single participant from a program using the given participant email.

#### Path Parameters

| Name                                               | Type   | Description                                            |
| -------------------------------------------------- | ------ | ------------------------------------------------------ |
| id<mark style="color:red;">\*</mark>               | string | The ID of the program to retrieve the participant from |
| participantEmail<mark style="color:red;">\*</mark> | string | The email address of the participant to retrieve       |

#### Response

{% tabs %}
{% tab title="200" %}
Returns the participant object.

```json
{
    "id": "f8g9nl",
    "firstName": "Gavin",
    "lastName": "Belson",
    "loyaltyActionCount": 2,
    "monthlyloyaltyActionCount": 2,
    "prevMonthlyLoyaltyActionCount": 0,
    "rank": 10001,
    "monthlyRank": 20001,
    "monthlyRank": -1,
    "email": "gavin@hoolie.com",
    "createdAt": 1552404738928,
    "fraudRiskLevel": "LOW",
    "fraudReasonCode": "UNIQUE_IDENTIY",
    "isWinner": true,
    "loyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "monthlyLoyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "loyaltyActionSource": "DIRECT",
    "ipAddress": "127.0.0.1",
    "fingerprint": "cfb163bd47ba666c52cb932c521e47f4",    
    "metadata": {
       "company": "Hooli, Inc",
       "companySize": 10000
    },
    "unsubscribed": false,
    "rewards": [
        {
            "id": "prew_9x8v1b",
            "rewardId": "crew_m5xm9l",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        },
        {
            "id": "prew_vsdj34",
            "rewardId": "crew_w01fil",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        },
        {
            "id": "prew_sj3kap",
            "rewardId": "crew_w01fil",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        }
    ]
}
```

{% endtab %}
{% endtabs %}

### Get Participants

<mark style="color:blue;">`GET`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/participants`

Retrieves a list of participants in the program.

#### Path Parameters

| Name                                 | Type   | Description           |
| ------------------------------------ | ------ | --------------------- |
| id<mark style="color:red;">\*</mark> | string | The ID of the program |

#### Query Parameters

| Name   | Type    | Description                                                                                                                                                                                                                                                                                                           |
| ------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| nextId | string  | <p>(Optional)<br><br>The ID of the participant to start the next result set with. This can be used to skip through the list or to page the list results. Each response will provide a <code>nextId</code> value if there are more participants otherwise the <code>nextId</code> value will be <code>null</code>.</p> |
| limit  | integer | <p>(Optional)<br><br>The number of participants to return. Must be a value less than or equal to 100 which is currently the maximum we allow with this request.</p>                                                                                                                                                   |

#### Response

{% tabs %}
{% tab title="200" %}
Returns the participant objects.

```json
{
    "participants": [
        {
            "id": "f8g9nl",
            "firstName": "Gavin",
            "lastName": "Belson",
            "loyaltyActionCount": 2,
            "monthlyloyaltyActionCount": 2,
            "prevMonthlyLoyaltyActionCount": 0,
            "rank": 10001,
            "monthlyRank": 20001,
            "monthlyRank": -1,
            "email": "gavin@hoolie.com",
            "createdAt": 1552404738928,
            "fraudRiskLevel": "LOW",
            "fraudReasonCode": "UNIQUE_IDENTIY",
            "isWinner": true,
            "loyaltyActionCountPerReward": {
                "crew_xfj7ic": 1
            },
            "monthlyLoyaltyActionCountPerReward": {
                "crew_xfj7ic": 1
            },
            "loyaltyActionSource": "DIRECT",
            "metadata": {
               "company": "Hooli, Inc",
               "companySize": 10000
            },
            "unsubscribed": false,
            "rewards": [
                {
                    "id": "prew_9x8v1b",
                    "rewardId": "crew_m5xm9l",
                    "status": "FULFILLED",
                    "unread": true,
                    "isAvailable": true,
                    "approved": true,
                    "isFulfilled": true
                },
                {
                    "id": "prew_vsdj34",
                    "rewardId": "crew_w01fil",
                    "status": "FULFILLED",
                    "unread": true,
                    "isAvailable": true,
                    "approved": true,
                    "isFulfilled": true
                },
                {
                    "id": "prew_sj3kap",
                    "rewardId": "crew_w01fil",
                    "status": "FULFILLED",
                    "unread": true,
                    "isAvailable": true,
                    "approved": true,
                    "isFulfilled": true
                }
            ]
        },
        {
            "id": "wskljf9",
            "firstName": "Spongebob",
            "lastName": "Squarepants",
            "loyaltyActionCount": 0,
            "monthlyLoyaltyActionCount": 0,
            "prevMonthlyLoyaltyActionCount": 0,
            "rank": 1540,
            "monthlyRank": 1540,
            "prevMonthlyRank": 1799,
            "email": "spongebob@nickelodeon.com",
            "createdAt": 1552404738928,
            "fraudRiskLevel": "LOW",
            "fraudReasonCode": "UNIQUE_IDENTIY",
            "isWinner": true,            
            "loyaltyActionSource": "MANUAL",
            "metadata": {},
            "unsubscribed": false,
            "rewards": []
        }
    ],
    "limit": 2,
    "nextId": "1u7v0q"
}
```

{% endtab %}
{% endtabs %}

### Get Leaderboard

<mark style="color:blue;">`GET`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/leaderboard`

Retrieves a list of participants in the program ordered by loyalty action count in ascending order.&#x20;

* **Monthly Loyalty Action Count Leaderboard**\
  \
  You can retrieve the program leaderboard ordered by the monthly loyalty action count by providing a query parameter `leaderboardType` with a value of `CURRENT_MONTH`. This will retrieve a list of participants ordered by monthly loyalty action.\
  \
  Monthly loyalty action counts are automatically reset at the end of each month for each participant within your program, therefore results of the monthly loyalty action count may vary.<br>
* **Previous Monthly Loyalty Action Count Leaderboard**\
  \
  Similar to the monthly program leaderboard, providing a query parameter of `leaderboardType` with a value of `PREV_MONTH` will retrieve a list of participants ordered by the previous monthly loyalty action count.\
  \
  Participants that did not exist within the program during the previous month will not be returned within the previous monthly leaderboard response.

#### Path Parameters

| Name                                 | Type   | Description           |
| ------------------------------------ | ------ | --------------------- |
| id<mark style="color:red;">\*</mark> | string | The ID of the program |

#### Query Parameters

| Name            | Type   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| --------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| nextId          | string | <p>(Optional)<br><br>The ID of the participant to start the next result set with. This can be used to skip through the list or to page the list of results. Each response will provide a <code>nextId</code> value if there are more participants otherwise, <code>nextId</code> will be <code>null</code>.</p>                                                                                                                                                                                                                                                                                                                        |
| limit           | string | <p>(Optional)<br><br>The number of participants to return. Must be a value less than or equal to 100 and greater than 1. 100 is currently the maximum limit per reach request.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| leaderboardType | string | <p>(Optional)<br><br>Returns the leaderboard for the specified type if provided.<br><br><strong>Options</strong><br><code>ALL\_TIME</code> - Returns the all-time leaderboard, based on all-time loyalty action counts. <em>Default</em><br><br><code>CURRENT\_MONTH</code> -  Returns the current month's leaderboard, based on the current month's loyalty action counts.<br><br><code>PREV\_MONTH</code> - Returns the previous month's leaderboard, based on the previous month's loyalty action counts (With this option, participants that did not exist within the program during the previous month will not be returned).</p> |

#### Response

{% tabs %}
{% tab title="200" %}
Example response of the standard leaderboard with returned participants ordered by their loyalty action count.

If the `leaderboardType=CURRENT_MONTH` query parameter is provided, the resulting list would be ordered by monthly loyalty action count.

Similarly, if `leaderboardType=PREV_MONTH` is provided, the resulting list would be ordered by the previous monthly loyalty action count.

```json
{
    "participants": [
        {
            "id": "f8g9nl",
            "firstName": "Gavin",
            "lastName": "Belson",
            "loyaltyActionCount": 2,
            "monthlyloyaltyActionCount": 2,
            "prevMonthlyLoyaltyActionCount": 0,
            "rank": 10001,
            "monthlyRank": 20001,
            "monthlyRank": -1,
            "email": "gavin@hoolie.com",
            "createdAt": 1552404738928,
            "fraudRiskLevel": "LOW",
            "fraudReasonCode": "UNIQUE_IDENTIY",
            "isWinner": true,
            "loyaltyActionCountPerReward": {
                "crew_xfj7ic": 1
            },
            "monthlyLoyaltyActionCountPerReward": {
                "crew_xfj7ic": 1
            },
            "loyaltyActionSource": "DIRECT",
            "ipAddress": "127.0.0.1",
            "fingerprint": "cfb163bd47ba666c52cb932c521e47f4",            
            "metadata": {
               "company": "Hooli, Inc",
               "companySize": 10000
            },
            "unsubscribed": false,
            "rewards": [
                {
                    "id": "prew_9x8v1b",
                    "rewardId": "crew_m5xm9l",
                    "status": "FULFILLED",
                    "unread": true,
                    "isAvailable": true,
                    "approved": true,
                    "isFulfilled": true
                },
                {
                    "id": "prew_vsdj34",
                    "rewardId": "crew_w01fil",
                    "status": "FULFILLED",
                    "unread": true,
                    "isAvailable": true,
                    "approved": true,
                    "isFulfilled": true
                },
                {
                    "id": "prew_sj3kap",
                    "rewardId": "crew_w01fil",
                    "status": "FULFILLED",
                    "unread": true,
                    "isAvailable": true,
                    "approved": true,
                    "isFulfilled": true
                }
            ]
        },
        {
            "id": "wskljf9",
            "firstName": "Spongebob",
            "lastName": "Squarepants",
            "loyaltyActionCount": 0,
            "monthlyLoyaltyActionCount": 0,
            "prevMonthlyLoyaltyActionCount": 0,
            "rank": 10002,
            "monthlyRank": 1540,
            "prevMonthlyRank": 1799,
            "email": "spongebob@nickelodeon.com",
            "createdAt": 1552404738928,
            "fraudRiskLevel": "LOW",
            "fraudReasonCode": "UNIQUE_IDENTIY",
            "isWinner": true,            
            "loyaltyActionSource": "MANUAL",
            "ipAddress": "113.2.2.9",
            "fingerprint": "dau221bd47ba661c51ca933d531e47f5",
            "metadata": {},
            "unsubscribed": false,
            "rewards": []
        }
    ],
    "limit": 2,
    "nextId": "1u7v0q"
}
```

{% endtab %}
{% endtabs %}

### Add Participant

<mark style="color:green;">`POST`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/participant`

Adds a participant to the program.

{% hint style="info" %}
**Tips:**

* The only required field is `email` .
* Though they are optional, we recommend passing in the fields `ipAddress`, `fingerprint`,  `firstName` , and `lastName` . These fields are used for anti-fraud purposes.
  {% endhint %}

#### Path Parameters

| Name                                 | Type   | Description                                         |
| ------------------------------------ | ------ | --------------------------------------------------- |
| id<mark style="color:red;">\*</mark> | string | The ID of the program to add the new participant to |

#### Request Body

| Name                                    | Type   | Description                                                                                                                                                                                                                                                                                                                                                                                 |
| --------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| email<mark style="color:red;">\*</mark> | string | The email address of the new participant                                                                                                                                                                                                                                                                                                                                                    |
| firstName                               | string | <p>(Optional, but recommended)</p><p><br>The first name of the new participant. If provided, this property will be used for anti-fraud measurements.</p>                                                                                                                                                                                                                                    |
| lastName                                | string | <p>(Optional, but recommended)</p><p><br>The last name of the new participant. If provided, this property will be used for anti-fraud measurements.</p>                                                                                                                                                                                                                                     |
| ipAddress                               | string | <p>(Optional, but recommended)</p><p><br>The IP address of the new participant. If provided, this property will be used for anti-fraud measurements.</p>                                                                                                                                                                                                                                    |
| fingerprint                             | string | <p>(Optional, but recommended)</p><p><br>The browser fingerprint of the new participant. If provided, this property will be used for anti-fraud measurements.<br><br>We recommend using a front-end library like <a href="https://github.com/fingerprintjs/fingerprintjs">fingerprintjs</a> to get the fingerprint value. Example value: <code>cfb163bd47ba666c52cb932c521e47f4</code>.</p> |
| metadata                                | object | <p>(Optional)<br><br>A shallow Object containing custom key/values to include with the participant data.<br><br>The following keys are restricted: <code>gdprAgreements</code></p>                                                                                                                                                                                                          |

#### Request Examples

{% tabs %}
{% tab title="cURL" %}
Here is an example `cURL` command you can use to call this API endpoint. Remember to replace `YOUR_PROGRAM_ID` with your program ID, `gavin@hooli.com` with the email address of the new participant you're adding, and `YOUR_API_KEY` with your API key.

We pass in `firstName`, `lastName`, `ipAddress` and `fingerprint` for anti-fraud purposes. `metadata` is used to save any custom data that can be retrieved later.

```bash
curl -X POST "https://api.loyaltysurf.io/v1/campaign/YOUR_PROGRAM_ID/participant" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
   "email": "gavin@hooli.com",
   "firstName": "Gavin",
   "lastName": "Belson",
   "ipAddress": "203.0.113.10",
   "metadata": {
      "companyName": "Hooli",
      "industry": "Software"
   }
}'
```

{% endtab %}
{% endtabs %}

#### Response

{% tabs %}
{% tab title="200" %}
Returns the participant object that was added to the program.

```json
{
    "id": "3vxff9",
    "firstName": "Gavin",
    "lastName": "Belson",
    "loyaltyActionCount": 0,
    "monthlyLoyaltyActionCount": 0,
    "prevMonthlyLoyaltyActionCount": 0,
    "rank": 10001,
    "monthlyRank": 10001,
    "rewards": [],
    "email": "gavin@hooli.com",
    "createdAt": 1558665537426,
    "loyaltyActionSource": "DIRECT",
    "fraudRiskLevel": "LOW",
    "fraudReasonCode": "UNIQUE_IDENTITY",
    "isWinner": false,
    "fraudRiskLevel": "LOW",
    "fraudReasonCode": "UNIQUE_IDENTITY",    
    "ipAddress": "127.0.0.1",
    "fingerprint": "cfb163bd47ba666c52cb932c521e47f4",    
    "metadata": {
       "company": "Hooli, Inc",
       "companySize": 10000
    }
    "unsubscribed": false,
}

```

{% endtab %}

{% tab title="400" %}
A `400` will be returned if validation fails on an input.

```javascript
{
  "name": "BadRequestError",
  "code": "BAD_REQUEST_ERROR",
  "message": "Invalid email foo",
  "errors": […],
  "status": 400,
  "supportUrl": "https://app.loyaltysurf.io/settings#contact_support"
}
```

{% endtab %}

{% tab title="422" %}
If the new participant is detected to be a high-level fraudster, and if anti-fraud settings are configured on the program, the participant will be blocked from joining with a status code of `422`.\
\
View the list of available `fraudRiskLevel` and `fraudReasonCode` options on the [Participant](https://docs.loyaltysurf.io/developer-tools/rest-api/api-objects#participant) Object. `matchedParticipantIds` will contain a list of matching fraudsters, but will be empty if an antifraud blacklist rule gets a match first.

```javascript
{
  "name": "ParticipantBlockedError",
  "code": "PARTICIPANT_BLOCKED_ERROR",
  "message": "Participant sarah.smith@email.com is blocked by antifraud rules.",
  "status": 422,
  "supportUrl": "https://app.loyaltysurf.io/settings#contact_support",
  "fraudRiskLevel": "HIGH",
  "fraudReasonCode": "BLACKLIST_MATCH",
  "matchedParticipantIds": [],
  "email": "sarah.smith@email.com",
  "ipAddress": "203.0.113.10",
  "fingerprint": null,
  "blockedAt": "2025-11-13T06:22:31.001Z"
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Metadata:** Please see our [API Guidelines ](https://docs.loyaltysurf.io/developer-tools/api-guidelines#metadata)for more information about `metadata.`
{% endhint %}

### Update Participant by ID

<mark style="color:green;">`POST`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantId`

Updates a participant within the program using the ID of the participant.

#### Path Parameters

| Name                                            | Type   | Description               |
| ----------------------------------------------- | ------ | ------------------------- |
| id<mark style="color:red;">\*</mark>            | string | The ID of the program     |
| participantId<mark style="color:red;">\*</mark> | string | The ID of the participant |

#### Request Body

| Name         | Type    | Description                                                                                                                                                                                                                                                                                                                                                                                        |
| ------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| email        | string  | <p>(Optional)<br><br>The new email to assign to this participant.<br><br>If the given email is already assigned to another participant within the program, an error response will be returned.</p>                                                                                                                                                                                                 |
| firstName    | string  | <p>(Optional)<br><br>The first name of the participant.</p>                                                                                                                                                                                                                                                                                                                                        |
| lastName     | string  | <p>(Optional)<br><br>The last name of the participant</p>                                                                                                                                                                                                                                                                                                                                          |
| metadata     | object  | <p>(Optional)<br><br>A shallow Object containing custom values to include in the participant data.<br><br>If any existing metadata exists for the participant, any new values provided will be appended to the existing metadata, any existing values provided will overwrite and replace the existing metadata.\*<br><br>To remove any existing metadata set its value to <code>null</code>. </p> |
| unsubscribed | boolean | <p>(Optional)<br><br>The participant's unsubscribed status. If <code>true</code>, they will not receive any program emails.</p>                                                                                                                                                                                                                                                                    |

#### Response

{% tabs %}
{% tab title="200" %}
Returns the updated participant object.

```json
{
    "id": "f8g9nl",
    "firstName": "Gavin",
    "lastName": "Belson",
    "loyaltyActionCount": 2,
    "monthlyloyaltyActionCount": 2,
    "prevMonthlyLoyaltyActionCount": 0,
    "rank": 10001,
    "monthlyRank": 20001,
    "monthlyRank": -1,
    "email": "gavin@hoolie.com",
    "createdAt": 1552404738928,
    "fraudRiskLevel": "LOW",
    "fraudReasonCode": "UNIQUE_IDENTIY",
    "isWinner": true,
    "loyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "monthlyLoyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "loyaltyActionSource": "DIRECT",
    "metadata": {
       "company": "Hooli, Inc",
       "companySize": 10000
    },
    "unsubscribed": false,
    "rewards": [
        {
            "id": "prew_9x8v1b",
            "rewardId": "crew_m5xm9l",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        },
        {
            "id": "prew_vsdj34",
            "rewardId": "crew_w01fil",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        },
        {
            "id": "prew_sj3kap",
            "rewardId": "crew_w01fil",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        }
    ]
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**\***&#x50;lease see our [API Guidelines ](https://docs.loyaltysurf.io/developer-tools/api-guidelines#metadata)for more information about `metadata.`
{% endhint %}

### Update Participant by Email

<mark style="color:green;">`POST`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantEmail`

Updates a participant within the program using the email address of the participant.

#### Path Parameters

| Name                                               | Type   | Description           |
| -------------------------------------------------- | ------ | --------------------- |
| id<mark style="color:red;">\*</mark>               | string | The program ID        |
| participantEmail<mark style="color:red;">\*</mark> | string | The participant email |

#### Request Body

| Name         | Type    | Description                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| email        | string  | <p>(Optional)<br><br>The new email to assign to the participant.<br><br>If the given email is already assigned to another participant within the program, an error response will be returned. </p>                                                                                                                                                                                                          |
| firstName    | string  | <p>(Optional)<br><br>The first name of the participant</p>                                                                                                                                                                                                                                                                                                                                                  |
| lastName     | string  | <p>(Optional)<br><br>The last name of the participant</p>                                                                                                                                                                                                                                                                                                                                                   |
| metadata     | object  | <p>(Optional)<br><br>A shallow Object containing custom values to include in the participant data.<br><br>If any existing metadata exists for the  participant, any new values provided will be appended to the existing participant metadata, any existing values provided will  overwrite and replace the existing metadata.\*<br><br>To remove existing metadata set its value to <code>null</code>.</p> |
| unsubscribed | boolean | <p>(Optional)<br><br>The participant's unsubscribed status. If <code>true</code>, they will not receive any program emails.</p>                                                                                                                                                                                                                                                                             |

#### Response

{% tabs %}
{% tab title="200" %}
Returns the updated participant object.

```json
{
    "id": "f8g9nl",
    "firstName": "Gavin",
    "lastName": "Belson",
    "loyaltyActionCount": 2,
    "monthlyloyaltyActionCount": 2,
    "prevMonthlyLoyaltyActionCount": 0,
    "rank": 10001,
    "monthlyRank": 20001,
    "monthlyRank": -1,
    "email": "gavin@hoolie.com",
    "createdAt": 1552404738928,
    "fraudRiskLevel": "LOW",
    "fraudReasonCode": "UNIQUE_IDENTIY",
    "isWinner": true,
    "loyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "monthlyLoyaltyActionCountPerReward": {
        "crew_xfj7ic": 1
    },
    "loyaltyActionSource": "DIRECT",
    "metadata": {
       "company": "Hooli, Inc",
       "companySize": 10000
    },   
    "unsubscribed": false,
    "rewards": [
        {
            "id": "prew_9x8v1b",
            "rewardId": "crew_m5xm9l",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        },
        {
            "id": "prew_vsdj34",
            "rewardId": "crew_w01fil",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        },
        {
            "id": "prew_sj3kap",
            "rewardId": "crew_w01fil",
            "status": "FULFILLED",
            "unread": true,
            "isAvailable": true,
            "approved": true,
            "isFulfilled": true
        }
    ]
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**\***&#x50;lease see our [API Guidelines ](https://docs.loyaltysurf.io/developer-tools/api-guidelines#metadata)for more information about `metadata.`
{% endhint %}

### Remove Participant by ID

<mark style="color:red;">`DELETE`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantId`

Removes a participant within the program using the ID of the participant.

#### Path Parameters

| Name                                            | Type   | Description               |
| ----------------------------------------------- | ------ | ------------------------- |
| id<mark style="color:red;">\*</mark>            | string | The ID of the program     |
| participantId<mark style="color:red;">\*</mark> | string | The ID of the participant |

#### Response

{% tabs %}
{% tab title="200" %}
Returns a success response.

```json
{
    "success": true
}
```

{% endtab %}
{% endtabs %}

### Remove Participant by Email

<mark style="color:red;">`DELETE`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantEmail`

Removes a participant within the program using the email address of the participant.

#### Path Parameters

| Name                                               | Type   | Description           |
| -------------------------------------------------- | ------ | --------------------- |
| id<mark style="color:red;">\*</mark>               | string | The camprogramaign ID |
| participantEmail<mark style="color:red;">\*</mark> | string | The participant email |

#### Response

{% tabs %}
{% tab title="200 Returns a success response." %}

```json
{
    "success": true
}
```

{% endtab %}
{% endtabs %}

***

## PARTICIPANT REWARDS ↓

### Get Participant Rewards by Participant ID

<mark style="color:blue;">`GET`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantId/rewards`

Retrieves a list of rewards earned by a participant.

#### Path Parameters

| Name                                            | Type   | Description                          |
| ----------------------------------------------- | ------ | ------------------------------------ |
| id<mark style="color:red;">\*</mark>            | string | The ID of the program                |
| participantId<mark style="color:red;">\*</mark> | string | The participant's unique ID or email |

#### Query Parameters

| Name   | Type   | Description                                                                                                                                                                                                                                                                                                          |
| ------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| nextId | string | <p>(Optional)<br><br>The ID of the participant reward to start the next result set with. This can be used to skip through the list or to page the list of results. Each response will provide a <code>nextId</code> value if there are more rewards otherwise the <code>nextId</code> will be <code>null</code>.</p> |
| limit  | string | <p>(Optional)<br><br>The number of rewards to return. Must be a value less than or equal to 100, which is currently the maximum allowed per request.</p>                                                                                                                                                             |

#### Response

{% tabs %}
{% tab title="200" %}
In this example we are showing two rewards earned by the participant.\
\
`status` will be `"PENDING"` if the reward has not yet been fulfilled, otherwise it will be `"FULFILLED"`.

`isAvailable` will be `true` if the reward has been approved either manually or automatically (depending on the program settings) and fulfilled, otherwise it will be set to `false`.

```json
{
    "limit": 2,
    "nextId": "prew_v2qtfq",
    "rewards": [
        {
            "id": "prew_rr35mg",
            "rewardId": "crew_c6w1qo",
            "status": "PENDING",
            "unread": true,
            "approved": false,
            "approvedAt": null,
            "fulfilledAt": null,            
            "isAvailable": false,
            "isFulfilled": false
        },
        {
            "id": "prew_oltj0s",
            "rewardId": "crew_c6w1qo",
            "status": "FULFILLED",
            "unread": false,
            "approved": true,  
            "approvedAt": 1659453091744,
            "fulfilledAt": 1659453418901,     
            "isAvailable": true,
            "isFulfilled": true
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}
Error response returned if the `limit` query parameter that is provided exceeds the maximum allowed amount.

```javascript
{
    "name": "BadRequestError",
    "code": "BAD_REQUEST_ERROR",
    "message": "Invalid request. Request params are missing or are invalid",
    "status": 400,
    "supportUrl": "https://app.loyaltysurf.io/settings#contact_support",
    "errors": [
        {
            "location": "query",
            "param": "limit",
            "value": "20",
            "msg": "Limit cannot be more than 10."
        }
    ],
    "level": "error",
    "timestamp": "2019-12-31T22:07:49.957Z"
}
```

{% endtab %}
{% endtabs %}

### Get Participant Rewards by Participant Email

<mark style="color:blue;">`GET`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantEmail/rewards`

Retrieves a list of rewards earned by a participant.

#### Path Parameters

| Name                                               | Type   | Description                          |
| -------------------------------------------------- | ------ | ------------------------------------ |
| id<mark style="color:red;">\*</mark>               | string | The ID of the program                |
| participantEmail<mark style="color:red;">\*</mark> | string | The email address of the participant |

#### Query Parameters

| Name   | Type   | Description                                                                                                                                                                                                                                                                                                          |
| ------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| nextId | string | <p>(Optional)<br><br>The ID of the participant reward to start the next result set with. This can be used to skip through the list or to page the list of results. Each response will provide a <code>nextId</code> value if there are more rewards otherwise the <code>nextId</code> will be <code>null</code>.</p> |
| limit  | string | <p>(Optional)<br><br>The number of rewards to return. Must be a value less than or equal to 100, which is currently the maximum allowed per request.</p>                                                                                                                                                             |

#### Response

{% tabs %}
{% tab title="200" %}
In this example we are showing two rewards earned by the participant.\
\
`status` will be `"PENDING"` if the reward has not yet been fulfilled, otherwise it will be `"FULFILLED"`.

`isAvailable` will be `true` if the reward has been approved either manually or automatically (depending on the program settings) and fulfilled, otherwise it will be set to `false`.

```json
{
    "limit": 2,
    "nextId": "prew_v2qtfq",
    "rewards": [
        {
            "id": "prew_rr35mg",
            "rewardId": "crew_c6w1qo",
            "status": "PENDING",
            "unread": true,
            "approved": false,      
            "approvedAt": null,
            "fulfilledAt": null,  
            "isAvailable": false,
            "isFulfilled": false
        },
        {
            "id": "prew_oltj0s",
            "rewardId": "crew_c6w1qo",
            "status": "FULFILLED",
            "unread": false,
            "approved": true,    
            "approvedAt": 1659453091744,
            "fulfilledAt": 1659453418901,
            "isAvailable": true,
            "isFulfilled": true
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}
Error response returned if the `limit` query parameter that is provided exceeds the maximum allowed amount.

```javascript
{
    "name": "BadRequestError",
    "code": "BAD_REQUEST_ERROR",
    "message": "Invalid request. Request params are missing or are invalid",
    "status": 400,
    "supportUrl": "https://app.loyaltysurf.io/settings#contact_support",
    "errors": [
        {
            "location": "query",
            "param": "limit",
            "value": "20",
            "msg": "Limit cannot be more than 10."
        }
    ],
    "level": "error",
    "timestamp": "2019-12-31T22:07:49.957Z"
}
```

{% endtab %}
{% endtabs %}

### Approve Participant Reward

<mark style="color:green;">`POST`</mark> `https://api.loyaltysurf.io/v2/campaign/:id/reward/:rewardId/approve`

Approve a reward that was earned by a participant.\
\
You should only use this endpoint if your reward automation level is set to *Manually approve rewards* (learn more [here](https://support.loyaltysurf.com/article/266-how-to-automate-rewards-fulfillment)). This means [`ParticipantRewards`](https://docs.loyaltysurf.io/integrate/rest-api/api-objects#participantreward) will be generated with `status: "PENDING"`, `approved: false`, and `isFulfilled: false`.&#x20;

Calling this endpoint to approve a reward will cause *New Participant Reward* emails to be sent out and automations/integrations to be triggered. If you are using Webhooks to automate rewards, a new [`PARTICIPANT_REACHED_A_GOAL`](https://docs.loyaltysurf.io/automate-rewards/webhooks/events-reference#participant_reached_a_goal) event will be emitted with `data.reward.approved` as `false`.

#### Path Parameters

| Name                                       | Type   | Description                                 |
| ------------------------------------------ | ------ | ------------------------------------------- |
| id<mark style="color:red;">\*</mark>       | string | The ID of the program                       |
| rewardId<mark style="color:red;">\*</mark> | string | The ID of the participant reward to approve |

#### Request Body

| Name    | Type    | Description                                                                                                                                                                                                                                           |
| ------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| fulfill | boolean | <p>(Optional)<br><br>Set <code>true</code> to mark the reward as fulfilled.</p><p></p><p>Fulfilling a reward does not trigger any emails or automations. It helps you stay organized when managing rewards from your LoyaltySurf admin dashboard.</p> |

#### Response

{% tabs %}
{% tab title="200" %}
Returns a success response.

```json
{
    "success": true
}
```

{% endtab %}

{% tab title="406" %}
Error response returned if a reward has already been approved for a participant.

```javascript
{
    "name": "InvalidRewardState",
    "code": "INVALID_REWARD_STATE",
    "message": "Invalid reward state. Reward has already been approved.",
    "status": 406,
    "supportUrl": "https://app.loyaltysurf.io/settings#contact_support",
    "level": "error",
    "timestamp": "2019-10-13T16:43:05.902Z"
}
```

{% endtab %}
{% endtabs %}

### Fulfill Participant Reward

<mark style="color:green;">`POST`</mark> `https://api.loyatysurf.io/v1/campaign/:id/reward/:rewardId/fulfill`

Fulfill a reward that was earned by a participant (this can only be done if the reward is already approved). When you call this endpoint, the [`ParticipantReward`](https://docs.loyaltysurf.io/integrate/rest-api/api-objects#participantreward) should have the following key-values: `status: "PENDING"`, `approved: true`, and `isFulfilled: false`.&#x20;

Fulfilling a reward does not trigger any emails or automations. It helps you stay organized when managing rewards from your LoyaltySurf admin dashboard.

#### Path Parameters

| Name                                       | Type   | Description                                 |
| ------------------------------------------ | ------ | ------------------------------------------- |
| id<mark style="color:red;">\*</mark>       | string | The ID of the program                       |
| rewardId<mark style="color:red;">\*</mark> | string | The ID of the participant reward to fulfill |

#### Response

{% tabs %}
{% tab title="200" %}
Returns a success response.

```json
{
    "success": true
}
```

{% endtab %}

{% tab title="406" %}
Error response returned if a reward has not been approved or has already been fulfilled.

```javascript
{
    "name": "InvalidRewardState",
    "code": "INVALID_REWARD_STATE",
    "message": "Invalid reward state. Reward has already been fulfilled.",
    "status": 406,
    "supportUrl": "https://app.loyaltysurf.io/settings#contact_support",
    "level": "error",
    "timestamp": "2019-10-13T16:43:05.902Z"
}
```

{% endtab %}
{% endtabs %}

### Remove Participant Reward

<mark style="color:red;">`DELETE`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/reward/:rewardId`

Remove a reward that was earned by a participant.\
\
This only applies if your program was configured with manual reward approval and if the provided participant reward has not been approved.

#### Path Parameters

| Name                                       | Type   | Description                                |
| ------------------------------------------ | ------ | ------------------------------------------ |
| id<mark style="color:red;">\*</mark>       | string | The ID of the program                      |
| rewardId<mark style="color:red;">\*</mark> | string | The ID of the participant reward to remove |

#### Response

{% tabs %}
{% tab title="200" %}
Returns a success response.

```json
{
    "success": true
}
```

{% endtab %}

{% tab title="406" %}
Error response returned if a reward has already been approved and thus cannot be deleted.

```javascript
{
    "name": "InvalidRewardState",
    "code": "INVALID_REWARD_STATE",
    "message": "Invalid reward state. This reward has already been approved and cannot be removed.",
    "status": 406,
    "supportUrl": "https://app.loyaltysurf.io/settings#contact_support",
    "level": "error",
    "timestamp": "2019-10-17T16:43:05.902Z"
}
```

{% endtab %}
{% endtabs %}

***

## ANALYTICS ↓

### Get Campaign Analytics

<mark style="color:blue;">`GET`</mark> `https://api.loyaltysurf.io/v1/campaign/:id/analytics`

Retrieves the analytics for a program.

#### Path Parameters

| Name                                 | Type    | Description                                                                                                                                                                                     |
| ------------------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id<mark style="color:red;">\*</mark> | string  | The ID of the program to retrieve analytics for.                                                                                                                                                |
| days                                 | integer | <p>(Optional) <br><br>The last number of days to retrieve analytics for. Defaults to <code>365</code> if no value is provided.  Maximum limit is <code>1825</code>.</p>                         |
| startDate                            | integer | <p>(Optional but required if <code>days</code> is not set)<br><br>The start date of the analytics timeframe as a Unix timestamp in milliseconds. Example value: <code>1592359793538</code>.</p> |
| endDate                              | integer | <p>(Optional but required if <code>days</code> is not set)<br><br>The end date of the analytics timeframe as a Unix timestamp in milliseconds. Example value: <code>1747879793538</code>.</p>   |

#### Response

{% tabs %}
{% tab title="200" %}
Returns an `analytics` object for the program.

```json
{
  "analytics": {
    "participants": 20,
    "loyaltyActions": 22,
    "rewardFormSubmissions": 34
  },
  "startDate": 1592359793538,
  "endDate": 1747879793538
}
```

{% endtab %}
{% endtabs %}
