API Reference
This reference documents the LoyaltySurf REST API, including all available public methods and examples of each.
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 campaign you're working on.
CAMPAIGNS ↓
Get Campaign
GET https://api.loyaltysurf.io/v1/campaign/:id
Retrieves a campaign for the given ID.
Path Parameters
id*
string
The ID of the campaign to retrieve
Response
Returns the campaign object.
{
"id": "abc123",
"name": "Pied Piper Advocate Program",
"loyaltyActionCount": 121,
"participantCount": 199,
"winnerCount": 1,
"status": "IN_PROGRESS",
"currencyISO": "USD",
"rewards": [
{
"id": "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"
}
]
}Get Campaigns
GET https://api.loyaltysurf.io/v1/campaigns
Retrieves a list of your campaigns. Campaigns that have been deleted will not be returned in this response.
Response
Returns the campaign objects.
{
"campaigns": [
{
"id": "abc123",
"name": "Pied Piper Advocate Program",
"loyaltyActionCount": 20500,
"participantCount": 40000,
"winnerCount": 1500,
"status": "IN_PROGRESS",
"currencyISO": "USD",
"rewards": [
{
"id": "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": "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"
}
]
}
]
}LOYALTY ACTIONS ↓
Trigger Loyalty Action by Email
POST 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 campaign as a participant if they do not already exist.
If the required number of loyalty actions of the campaign reward is reached, then the reward will be unlocked.
Path Parameters
id*
string
The ID of the campaign
Request Body
participantEmail*
string
The email 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*
string
The campaign reward ID that the participant will earn upon completing the required number of loyalty actions.
addParticipantIfNoneExists
boolean
Adds the person to the campaign as a participant if they do not already exist. Defaults to true.
firstName
string
(Applies only if addParticipantIfNoneExists is true. Optional, but recommended)
The first name of the new participant. If provided, this property will be used for anti-fraud measurements.
lastName
string
(Applies only if addParticipantIfNoneExists is true. Optional, but recommended)
The last name of the new participant. If provided, this property will be used for anti-fraud measurements.
ipAddress
string
(Applies only if addParticipantIfNoneExists is true. Optional, but recommended)
The IP address of the new participant. If provided, this property will be used for anti-fraud measurements.
fingerprint
string
(Applies only if addParticipantIfNoneExists is true. Optional, but recommended)
The browser fingerprint of the new participant. If provided, this property will be used for anti-fraud measurements.
We recommend using a front-end library like fingerprintjs to get the fingerprint value. Example value: cfb163bd47ba666c52cb932c521e47f4.
metadata
object
(Applies only if addParticipantIfNoneExists is true. Optional)
A shallow Object containing custom key/values to include with the participant data.
Response
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.
{
"success": true,
"message": "Successfully awarded loyalty action credit.",
"participant": {
"campaignId": "6396fbff31a4f20865f4ae93",
"id": "cq3e6a",
"createdAt": "2022-12-14T08:58:10.019Z",
"email": "[email protected]",
"fraudReasonCode": "UNIQUE_IDENTITY",
"fraudRiskLevel": "LOW",
"hasRewards": true,
"isWinner": false,
"loyaltyActionCount": 1,
"loyaltyActionSource": "DIRECT",
"monthlyLoyaltyActionCount": 1,
"prevMonthlyLoyaltyActionCount": 0,
"sanitizedEmail": "[email protected]",
"unapprovedRewardsCount": 1,
"unfulfilledRewardsCount": 1,
"unsubscribed": false,
"updatedAt": "2022-12-14T08:58:10.407Z",
"welcomeEmailSent": true,
"loyaltyActionCountPerReward": {
"xfj7ic": 1
},
"monthlyLoyaltyActionCountPerReward": {
"xfj7ic": 1
}
}
}
}A 400 will be returned if validation fails on an input.
{
"name": "BadRequestError",
"code": "BAD_REQUEST_ERROR",
"message": "Invalid email foo",
"errors": […],
"status": 400,
"supportUrl": "https://app.loyaltysurf.io/settings#contact_support"
}A 409 error will be returned if the request is a duplicate.
{
"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"
}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 Object. matchedParticipantIds will contain a list of matching fraudsters, but will be empty if an antifraud blacklist rule gets a match first.
{
"name": "ParticipantBlockedError",
"code": "PARTICIPANT_BLOCKED_ERROR",
"message": "Participant [email protected] is blocked by antifraud rules.",
"status": 422,
"supportUrl": "https://app.loyaltysurf.io/settings#contact_support",
"fraudRiskLevel": "HIGH",
"fraudReasonCode": "BLACKLIST_MATCH",
"matchedParticipantIds": [],
"email": "[email protected]",
"ipAddress": "203.0.113.10",
"fingerprint": null,
"blockedAt": "2025-11-13T06:22:31.001Z"
}Metadata: Please see our API Guidelines for more information about metadata.
Trigger Loyalty Action by Participant ID
POST 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 campaign reward is reached, then the reward will be unlocked.
Path Parameters
id*
string
The ID of the campaign
Request Body
participantId*
string
The ID of the participant that performed the loyalty action.
rewardId*
String
The campaign reward ID that the participant will earn upon completing the required number of loyalty actions.
Response
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].
{
"success": true,
"message": "Successfully awarded loyalty action credit.",
"participant": {
"campaignId": "6396fbff31a4f20865f4ae93",
"id": "cq3e6a",
"createdAt": "2022-12-14T08:58:10.019Z",
"email": "[email protected]",
"fraudReasonCode": "UNIQUE_IDENTITY",
"fraudRiskLevel": "LOW",
"hasRewards": true,
"isWinner": false,
"loyaltyActionCount": 1,
"loyaltyActionSource": "DIRECT",
"monthlyLoyaltyActionCount": 1,
"prevMonthlyLoyaltyActionCount": 0,
"sanitizedEmail": "[email protected]",
"unapprovedRewardsCount": 1,
"unfulfilledRewardsCount": 1,
"unsubscribed": false,
"updatedAt": "2022-12-14T08:58:10.407Z",
"welcomeEmailSent": true,
"loyaltyActionCountPerReward": {
"xfj7ic": 1
},
"monthlyLoyaltyActionCountPerReward": {
"xfj7ic": 1
}
}
}
}A 400 will be returned if validation fails on an input.
{
"name": "BadRequestError",
"code": "BAD_REQUEST_ERROR",
"message": "Invalid email foo",
"errors": […],
"status": 400,
"supportUrl": "https://app.loyaltysurf.io/settings#contact_support"
}A 409 error will be returned if the request is a duplicate.
{
"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"
}PARTICIPANTS ↓
Get Participant by ID
GET https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantId
Retrieves a single participant from a campaign using the given participant ID.
Path Parameters
id*
string
The ID of the campaign to retrieve the participant from
participantId*
string
The ID of the participant to retrieve
Response
Returns the participant object.
{
"id": "f8g9nl",
"firstName": "Gavin",
"lastName": "Belson",
"loyaltyActionCount": 2,
"monthlyloyaltyActionCount": 2,
"prevMonthlyLoyaltyActionCount": 0,
"rank": 10001,
"monthlyRank": 20001,
"monthlyRank": -1,
"email": "[email protected]",
"createdAt": 1552404738928,
"fraudRiskLevel": "LOW",
"fraudReasonCode": "UNIQUE_IDENTIY",
"isWinner": true,
"loyaltyActionCountPerReward": {
"xfj7ic": 1
},
"monthlyLoyaltyActionCountPerReward": {
"xfj7ic": 1
},
"loyaltyActionSource": "DIRECT",
"ipAddress": "127.0.0.1",
"fingerprint": "cfb163bd47ba666c52cb932c521e47f4",
"metadata": {
"company": "Hooli, Inc",
"companySize": 10000
},
"unsubscribed": false,
"rewards": [
{
"id": "9x8v1b",
"rewardId": "m5xm9l",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "vsdj34",
"rewardId": "w01fil",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "sj3kap",
"rewardId": "w01fil",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
}
]
}Get Participant by Email
GET https://api.loyaltysurf.com/v1/campaign/:id/participant/:participantEmail
Retrieves a single participant from a campaign using the given participant email.
Path Parameters
id*
string
The ID of the campaign to retrieve the participant from
participantEmail*
string
The email of the participant to retrieve
Response
Returns the participant object.
{
"id": "f8g9nl",
"firstName": "Gavin",
"lastName": "Belson",
"loyaltyActionCount": 2,
"monthlyloyaltyActionCount": 2,
"prevMonthlyLoyaltyActionCount": 0,
"rank": 10001,
"monthlyRank": 20001,
"monthlyRank": -1,
"email": "[email protected]",
"createdAt": 1552404738928,
"fraudRiskLevel": "LOW",
"fraudReasonCode": "UNIQUE_IDENTIY",
"isWinner": true,
"loyaltyActionCountPerReward": {
"xfj7ic": 1
},
"monthlyLoyaltyActionCountPerReward": {
"xfj7ic": 1
},
"loyaltyActionSource": "DIRECT",
"ipAddress": "127.0.0.1",
"fingerprint": "cfb163bd47ba666c52cb932c521e47f4",
"metadata": {
"company": "Hooli, Inc",
"companySize": 10000
},
"unsubscribed": false,
"rewards": [
{
"id": "9x8v1b",
"rewardId": "m5xm9l",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "vsdj34",
"rewardId": "w01fil",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "sj3kap",
"rewardId": "w01fil",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
}
]
}Get Participants
GET https://api.loyaltysurf.io/v1/campaign/:id/participants
Retrieves a list of participants in the campaign.
Path Parameters
id*
string
The ID of the campaign
Query Parameters
nextId
string
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 nextId value if there are more participants otherwise the nextId value will be null.
limit
integer
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.
Response
Returns the participant objects.
{
"participants": [
{
"id": "f8g9nl",
"firstName": "Gavin",
"lastName": "Belson",
"loyaltyActionCount": 2,
"monthlyloyaltyActionCount": 2,
"prevMonthlyLoyaltyActionCount": 0,
"rank": 10001,
"monthlyRank": 20001,
"monthlyRank": -1,
"email": "[email protected]",
"createdAt": 1552404738928,
"fraudRiskLevel": "LOW",
"fraudReasonCode": "UNIQUE_IDENTIY",
"isWinner": true,
"loyaltyActionCountPerReward": {
"xfj7ic": 1
},
"monthlyLoyaltyActionCountPerReward": {
"xfj7ic": 1
},
"loyaltyActionSource": "DIRECT",
"metadata": {
"company": "Hooli, Inc",
"companySize": 10000
},
"unsubscribed": false,
"rewards": [
{
"id": "9x8v1b",
"rewardId": "m5xm9l",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "vsdj34",
"rewardId": "w01fil",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "sj3kap",
"rewardId": "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": "[email protected]",
"createdAt": 1552404738928,
"fraudRiskLevel": "LOW",
"fraudReasonCode": "UNIQUE_IDENTIY",
"isWinner": true,
"loyaltyActionSource": "MANUAL",
"metadata": {},
"unsubscribed": false,
"rewards": []
}
],
"limit": 2,
"nextId": "1u7v0q"
}Get Leaderboard
GET https://api.loyaltysurf.io/v1/campaign/:id/leaderboard
Retrieves a list of participants in the campaign ordered by loyalty action count in ascending order.
Monthly Loyalty Action Count Leaderboard You can retrieve the campaign leaderboard ordered by the monthly loyalty action count by providing a query parameter
leaderboardTypewith a value ofCURRENT_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 campaign, therefore results of the monthly loyalty action count may vary.Previous Monthly Loyalty Action Count Leaderboard Similar to the monthly campaign leaderboard, providing a query parameter of
leaderboardTypewith a value ofPREV_MONTHwill retrieve a list of participants ordered by the previous monthly loyalty action count. Participants that did not exist within the campaign during the previous month will not be returned within the previous monthly leaderboard response.
Path Parameters
id*
string
The ID of the campaign
Query Parameters
nextId
string
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 nextId value if there are more participants otherwise, nextId will be null.
limit
string
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.
leaderboardType
string
Returns the leaderboard for the specified type if provided.
Options
ALL_TIME - Returns the all-time leaderboard, based on all-time loyalty action counts. Default
CURRENT_MONTH - Returns the current month's leaderboard, based on the current month's loyalty action counts.
PREV_MONTH - 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 campaign during the previous month will not be returned).
Response
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.
{
"participants": [
{
"id": "f8g9nl",
"firstName": "Gavin",
"lastName": "Belson",
"loyaltyActionCount": 2,
"monthlyloyaltyActionCount": 2,
"prevMonthlyLoyaltyActionCount": 0,
"rank": 10001,
"monthlyRank": 20001,
"monthlyRank": -1,
"email": "[email protected]",
"createdAt": 1552404738928,
"fraudRiskLevel": "LOW",
"fraudReasonCode": "UNIQUE_IDENTIY",
"isWinner": true,
"loyaltyActionCountPerReward": {
"xfj7ic": 1
},
"monthlyLoyaltyActionCountPerReward": {
"xfj7ic": 1
},
"loyaltyActionSource": "DIRECT",
"ipAddress": "127.0.0.1",
"fingerprint": "cfb163bd47ba666c52cb932c521e47f4",
"metadata": {
"company": "Hooli, Inc",
"companySize": 10000
},
"unsubscribed": false,
"rewards": [
{
"id": "9x8v1b",
"rewardId": "m5xm9l",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "vsdj34",
"rewardId": "w01fil",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "sj3kap",
"rewardId": "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": "[email protected]",
"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"
}Add Participant
POST https://api.loyaltysurf.io/v1/campaign/:id/participant
Adds a participant to the campaign.
Path Parameters
id*
string
The ID of the campaign to add the new participant to
Request Body
email*
string
The email of the new participant
firstName
string
(Optional, but recommended) The first name of the new participant. If provided, this property will be used for anti-fraud measurements.
lastName
string
(Optional, but recommended) The last name of the new participant. If provided, this property will be used for anti-fraud measurements.
ipAddress
string
(Optional, but recommended) The IP address of the new participant. If provided, this property will be used for anti-fraud measurements.
fingerprint
string
(Optional, but recommended) The browser fingerprint of the new participant. If provided, this property will be used for anti-fraud measurements.
We recommend using a front-end library like fingerprintjs to get the fingerprint value. Example value: cfb163bd47ba666c52cb932c521e47f4.
metadata
object
A shallow Object containing custom key/values to include with the participant data.
The following keys are restricted: gdprAgreements
Request Examples
Here is an example cURL command you can use to call this API endpoint. Remember to replace YOUR_CAMPAIGN_ID with your campaign ID, [email protected] 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.
curl -X POST "https://api.loyaltysurf.io/v1/campaign/YOUR_CAMPAIGN_ID/participant" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"firstName": "Gavin",
"lastName": "Belson",
"ipAddress": "203.0.113.10",
"metadata": {
"companyName": "Hooli",
"industry": "Software"
}
}'Response
Returns the participant object that was added to the campaign.
{
"id": "3vxff9",
"firstName": "Gavin",
"lastName": "Belson",
"loyaltyActionCount": 0,
"monthlyLoyaltyActionCount": 0,
"prevMonthlyLoyaltyActionCount": 0,
"rank": 10001,
"monthlyRank": 10001,
"rewards": [],
"email": "[email protected]",
"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,
}
A 400 will be returned if validation fails on an input.
{
"name": "BadRequestError",
"code": "BAD_REQUEST_ERROR",
"message": "Invalid email foo",
"errors": […],
"status": 400,
"supportUrl": "https://app.loyaltysurf.io/settings#contact_support"
}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 Object. matchedParticipantIds will contain a list of matching fraudsters, but will be empty if an antifraud blacklist rule gets a match first.
{
"name": "ParticipantBlockedError",
"code": "PARTICIPANT_BLOCKED_ERROR",
"message": "Participant [email protected] is blocked by antifraud rules.",
"status": 422,
"supportUrl": "https://app.loyaltysurf.io/settings#contact_support",
"fraudRiskLevel": "HIGH",
"fraudReasonCode": "BLACKLIST_MATCH",
"matchedParticipantIds": [],
"email": "[email protected]",
"ipAddress": "203.0.113.10",
"fingerprint": null,
"blockedAt": "2025-11-13T06:22:31.001Z"
}Metadata: Please see our API Guidelines for more information about metadata.
Update Participant by ID
POST https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantId
Updates a participant within the campaign using the ID of the participant.
Path Parameters
id*
string
The ID of the campaign
participantId*
string
The ID of the participant
Request Body
string
The new email to assign to this participant. If the given email is already assigned to another participant within the campaign, an error response will be returned.
firstName
string
The first name of the participant.
lastName
string
The last name of the participant
metadata
object
A shallow Object containing custom values to include in the participant data.
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.*
To remove any existing metadata set its value to null.
unsubscribed
boolean
The participant's unsubscribed status. If true, they will not receive any campaign emails.
Response
Returns the updated participant object.
{
"id": "f8g9nl",
"firstName": "Gavin",
"lastName": "Belson",
"loyaltyActionCount": 2,
"monthlyloyaltyActionCount": 2,
"prevMonthlyLoyaltyActionCount": 0,
"rank": 10001,
"monthlyRank": 20001,
"monthlyRank": -1,
"email": "[email protected]",
"createdAt": 1552404738928,
"fraudRiskLevel": "LOW",
"fraudReasonCode": "UNIQUE_IDENTIY",
"isWinner": true,
"loyaltyActionCountPerReward": {
"xfj7ic": 1
},
"monthlyLoyaltyActionCountPerReward": {
"xfj7ic": 1
},
"loyaltyActionSource": "DIRECT",
"metadata": {
"company": "Hooli, Inc",
"companySize": 10000
},
"unsubscribed": false,
"rewards": [
{
"id": "9x8v1b",
"rewardId": "m5xm9l",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "vsdj34",
"rewardId": "w01fil",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "sj3kap",
"rewardId": "w01fil",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
}
]
}*Please see our API Guidelines for more information about metadata.
Update Participant by Email
POST https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantEmail
Updates a participant within the campaign using the email of the participant.
Path Parameters
id*
string
The campaign ID
participantEmail*
string
The participant email
Request Body
string
The new email to assign to the participant. If the given email is already assigned to another participant within the campaign, an error response will be returned.
firstName
string
The first name of the participant
lastName
string
The last name of the participant
metadata
object
A shallow Object containing custom values to include in the participant data.
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.*
To remove existing metadata set its value to null.
unsubscribed
boolean
The participant's unsubscribed status. If true, they will not receive any campaign emails.
Response
Returns the updated participant object.
{
"id": "f8g9nl",
"firstName": "Gavin",
"lastName": "Belson",
"loyaltyActionCount": 2,
"monthlyloyaltyActionCount": 2,
"prevMonthlyLoyaltyActionCount": 0,
"rank": 10001,
"monthlyRank": 20001,
"monthlyRank": -1,
"email": "[email protected]",
"createdAt": 1552404738928,
"fraudRiskLevel": "LOW",
"fraudReasonCode": "UNIQUE_IDENTIY",
"isWinner": true,
"loyaltyActionCountPerReward": {
"xfj7ic": 1
},
"monthlyLoyaltyActionCountPerReward": {
"xfj7ic": 1
},
"loyaltyActionSource": "DIRECT",
"metadata": {
"company": "Hooli, Inc",
"companySize": 10000
},
"unsubscribed": false,
"rewards": [
{
"id": "9x8v1b",
"rewardId": "m5xm9l",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "vsdj34",
"rewardId": "w01fil",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
},
{
"id": "sj3kap",
"rewardId": "w01fil",
"status": "FULFILLED",
"unread": true,
"isAvailable": true,
"approved": true,
"isFulfilled": true
}
]
}*Please see our API Guidelines for more information about metadata.
Remove Participant by ID
DELETE https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantId
Removes a participant within the campaign using the ID of the participant.
Path Parameters
id*
string
The ID of the campaign
participantId*
string
The ID of the participant
Response
Returns a success response.
{
"success": true
}Remove Participant by Email
DELETE https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantEmail
Removes a participant within the campaign using the email of the participant.
Path Parameters
id*
string
The campaign ID
participantEmail*
string
The participant email
Response
{
"success": true
}PARTICIPANT REWARDS ↓
Get Participant Rewards by Participant ID
GET https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantId/rewards
Retrieves a list of rewards earned by a participant.
Path Parameters
id*
string
The campaign ID
participantId*
string
The participant's unique ID or email
Query Parameters
nextId
string
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 nextId value if there are more rewards otherwise the nextId will be null.
limit
string
The number of rewards to return. Must be a value less than or equal to 100, which is currently the maximum allowed per request.
Response
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 campaign settings) and fulfilled, otherwise it will be set to false.
{
"limit": 2,
"nextId": "v2qtfq",
"rewards": [
{
"id": "rr35mg",
"rewardId": "c6w1qo",
"status": "PENDING",
"unread": true,
"approved": false,
"approvedAt": null,
"fulfilledAt": null,
"isAvailable": false,
"isFulfilled": false
},
{
"id": "oltj0s",
"rewardId": "c6w1qo",
"status": "FULFILLED",
"unread": false,
"approved": true,
"approvedAt": 1659453091744,
"fulfilledAt": 1659453418901,
"isAvailable": true,
"isFulfilled": true
}
]
}Error response returned if the limit query parameter that is provided exceeds the maximum allowed amount.
{
"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"
}Get Participant Rewards by Participant Email
GET https://api.loyaltysurf.io/v1/campaign/:id/participant/:participantEmail/rewards
Retrieves a list of rewards earned by a participant.
Paging this response
Each response will contain a nextId, that value is the id of the next participant and not the email therefore, you must use this endpoint in conjunction of our Get Participant Rewards by ID endpoint if you wish to page results starting with this endpoint. To page you would provide the nextId as the participantId path parameter within the Get Participant Rewards by ID request.
Path Parameters
id*
string
The id of the campaign.
participantEmail*
string
The participant email
Query Parameters
nextId
string
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 nextId value if there are more rewards otherwise the nextId will be null.
limit
string
The number of rewards to return. Must be a value less than or equal to 100, which is currently the maximum allowed per request.
Response
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 campaign settings) and fulfilled, otherwise it will be set to false.
{
"limit": 2,
"nextId": "v2qtfq",
"rewards": [
{
"id": "rr35mg",
"rewardId": "c6w1qo",
"status": "PENDING",
"unread": true,
"approved": false,
"approvedAt": null,
"fulfilledAt": null,
"isAvailable": false,
"isFulfilled": false
},
{
"id": "oltj0s",
"rewardId": "c6w1qo",
"status": "FULFILLED",
"unread": false,
"approved": true,
"approvedAt": 1659453091744,
"fulfilledAt": 1659453418901,
"isAvailable": true,
"isFulfilled": true
}
]
}Error response returned if the limit query parameter that is provided exceeds the maximum allowed amount.
{
"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"
}Approve Participant Reward
POST 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). This means ParticipantRewards will be generated with status: "PENDING", approved: false, and isFulfilled: false.
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 event will be emitted with data.reward.approved as false.
Path Parameters
id*
string
The campaign ID
rewardId*
string
The ID of the participant reward to approve
Request Body
fulfill
boolean
Set true to mark the reward as fulfilled.
Fulfilling a reward does not trigger any emails or automations. It helps you stay organized when managing rewards from your LoyaltySurf admin dashboard.
Response
Returns a success response.
{
"success": true
}Error response returned if a reward has already been approved for a participant.
{
"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"
}Fulfill Participant Reward
POST 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 should have the following key-values: status: "PENDING", approved: true, and isFulfilled: false.
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
id*
string
The campaign ID
rewardId*
string
The ID of the participant reward to fulfill
Response
Returns a success response.
{
"success": true
}Error response returned if a reward has not been approved or has already been fulfilled.
{
"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"
}Remove Participant Reward
DELETE https://api.loyaltysurf.io/v1/campaign/:id/reward/:rewardId
Remove a reward that was earned by a participant. This only applies if your campaign was configured with manual reward approval and if the provided participant reward has not been approved.
Path Parameters
id*
string
The campaign ID
rewardId*
string
The ID of the participant reward to remove
Response
Returns a success response.
{
"success": true
}Error response returned if a reward has already been approved and thus cannot be deleted.
{
"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"
}ANALYTICS ↓
Get Campaign Analytics
GET https://api.loyaltysurf.io/v1/campaign/:id/analytics
Retrieves the analytics for a campaign.
Path Parameters
id*
string
The ID of the campaign to retrieve analytics for.
days
integer
(Optional)
The last number of days to retrieve analytics for. Defaults to 365 if no value is provided. Maximum limit is 1825.
startDate
integer
(Optional but required if days is not set)
The start date of the analytics timeframe as a Unix timestamp in milliseconds. Example value: 1592359793538.
endDate
integer
(Optional but required if days is not set)
The end date of the analytics timeframe as a Unix timestamp in milliseconds. Example value: 1747879793538.
Response
Returns an analytics object for the campaign.
{
"analytics": {
"participants": 20,
"loyaltyActions": 22,
"rewardFormSubmissions": 34
},
"startDate": 1592359793538,
"endDate": 1747879793538
}Last updated
Was this helpful?