Overview
Loyalty Now uses webhooks to notify your application when relevant events happen in your program. You can utilise this functionality to receive data as it happens without polling the API or to get the data in a different service for additional functions.
Each webhook requires an HTTPS URL to be registered. To register a webhook use the Register end point found under Web Hook Management, here. You are able to register up to 5 urls per event.
Loyalty Now sends the data via HTTP POST in the following JSON format.
{
"hook": "card.added", // the name of the hook event that happened
"data": {} // The data is specific for each type of hook,
"sequence": 323 // a globally unique identifier for this data being sent
}
Webhook Delivery Policy
To successfully confirm the receipt and processing of a webhook event from Loyalty Now, your server endpoint must always return an HTTP status code of 200 (OK). Any other HTTP status code (including 2xx codes other than 200, all 3xx, 4xx, and 5xx codes) will be treated as a delivery failure.
If your system encounters an internal error or validation issue with the received data, do not return an error status code. Instead, handle the failure internally by logging the issue and triggering an administrative alert or notification so someone in your team can investigate the failed event.
Automatic Retry Mechanism
When a delivery fails, Loyalty Now may attempt to automatically retry sending the webhook up to 5 times over approximately one hour, using growing delays (an exponential backoff strategy) between attempts.
In general, most status codes that indicate a transient error (like server issues or timeouts) or an actionable error (like rate limiting) will trigger a retry. Some examples are outlined below.
Status Code Description
500 Internal Server Error Indicates a generic, temporary server-side issue on your end.
502 Bad Gateway Indicates an upstream proxy/gateway issue.
503 Service Unavailable Indicates your server is temporarily overloaded or down for maintenance.
504 Gateway Timeout Indicates a network or proxy timeout issue.
408 Request Timeout Indicates that your server didn't respond quickly enough.
429 Too Many Requests Indicates your server is rate-limiting our requests. We'll wait and try again.
Status codes that signal a permanent issue with the request or integration setup (like 400 Bad Request or 404 Not Found) may not be retried.
Persistent failures may indicate an issue with your webhook end-point/integration. If high volumes of failures, your webhook registration may be disabled to prevent data processing errors in your system.
Available Webhooks
The hooks that are currently available are:
[
{
"type": "Transaction",
"events": ["transaction.pending", "transaction.confirmed", "transaction.reversed"]
},
{
"type": "Card",
"events": ["card.added", "card.verified", "card.updated", "card.removed"]
},
{
"type": "Invoice",
"events": ["invoice.raised", "invoice.paid", "invoice.paymenterror", "invoice.sent"]
},
{
"type": "Payment",
"events": ["payment.raised", "payment.paid"]
},
{
"type": "SchemeRegistration",
"events": [
"schemeregistration.added",
"schemeregistration.updated",
"schemeregistration.register",
"schemeregistration.removed"
]
},
{
"type": "MerchantSignature",
"events": ["merchantsignature.added"]
},
{
"type": "Merchant",
"events": [
"merchant.added",
"merchant.updated",
"merchant.archived",
"merchant.closed",
"merchant.removed"
]
},
{
"type": "Member",
"events": ["member.added", "member.updated", "member.removed"]
},
{
"type": "MemberRewardAccount",
"events": [
"memberrewardaccount.reward",
"memberrewardaccount.rewardfunded",
"memberrewardaccount.rewardreversal",
"memberrewardaccount.withdrawal",
"memberrewardaccount.withdrawalpaid",
"memberrewardaccount.withdrawalreversed",
"memberrewardaccount.rewardremoved"
]
},
{
"type": "MerchantFeeAccount",
"events": [
"merchantfeeaccount.unconfirmed",
"merchantfeeaccount.confirmed",
"merchantfeeaccount.invoiced",
"merchantfeeaccount.removed",
"merchantfeeaccount.reversed",
"merchantfeeaccount.pending",
"merchantfeeaccount.paid"
]
},
{
"type": "ProgramCostAccount",
"events": ["programcostaccount.unconfirmed", "programcostaccount.confirmed"]
},
{
"type": "Offer",
"events": [
"offer.platformofferadded",
"offer.platformofferupdated",
"offer.programofferadded",
"offer.programofferupdated",
"offer.programofferdeleted",
"offer.programofferended",
"offer.baselineadded",
"offer.baselineupdated",
"offer.baselinedeleted",
"offer.baselineended",
"offer.merchantofferapproved",
"offer.merchantofferended",
"offer.campaignacceptedbymerchant",
"offer.campaignmerchantremoved",
"offer.offerbudgetthresholdreached",
"offer.offerbudgetreached",
"offer.boostaddedforoffer",
"offer.boostupdatedforoffer",
"offer.boostendedforoffer",
"offer.boostdeletedforoffer"
]
},
{
"type": "MerchantOffer",
"events": [
"merchantoffer.merchantoffercreated",
"merchantoffer.merchantofferupdated",
"merchantoffer.merchantofferapproved",
"merchantoffer.merchantofferrejected",
"merchantoffer.merchantofferended",
"merchantoffer.merchantofferdeleted"
]
}
]