Redemptions Webhook
Communicate with your customers based on platform activity or transactional behavior
How It Works
Webhooks enable you to communicate with your customers based on platform activity or transactional behavior. Explore the examples below and the diagram, followed by the section on how to build webhooks.
Examples
-
Redemption close-the-loop notifications. Using this webhook, you can communicate at the time of swipe that your customer's purchase has qualified for a reward, and that their redemption is in progress. For a description of Redemption properties and types, see the API Reference Redemption list.
-
Activity-based communication. This webhook works as follows:
As a Publisher, you pass authentication data to Cardlytics through the Transaction API.
Next, Cardlytics processes the authentication data to match the offer:
- Match to the right merchant
- Match to one or more valid offers
- Determine qualifying events
Cardlytics then shares the qualifying event through the Publisher-managed Webhook, as described in the section below.
In the end, the Publisher initiates customer messaging, congratulating them on the earned reward.
At a Glance
Activity-based communication is illustrated in the diagram below:

How to Set up RTM
Authentication
JWT + IP Whitelisting (Publisher will share IP addresses)
JWT Signing
Each webhook request will be signed using a JWT. The JWT should be signed with the sender's private key.
Verification
The receiver will verify the JWT using the sender's public key.
Key Handling
- Public Key: The sender will provide the public key that corresponds to their private signing key. (Public key extracted from the cert shared for mTLS auth)
openssl x509 -in 24_1101_publisher_prod_clientcert.pem -pubkey -noout > publickey.pem
Rotation
Automated key rotation is not required. In case of a private key compromise, the sender should notify the receiver out of band with the new public key. The receiver will then update their system to accept signatures from both the old and new keys, enabling a smooth rotation process.
Expiration
Each JWT will have a short expiration time (10 minutes), and a new token will be generated for every request.
JWT Token Sample
Encoded with sample private key:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkOGZlNzczZS1lMzExLTExZWYtODcxOS05YTY1NTZkNmQxMTUiLCJpc3MiOiJodHRwczovL3d3dy5jYXJkbHl0aWNzLmNvbSIsInN1YiI6IlB1Ymxpc2hlciIsImlhdCI6MTc0MDU0NjM5Mi42MTA4NSwiZXhwIjoxNzQwNTQ2NjkyLjYxMDg1LCJraWQiOiJLZXlfdjEifQ.NQzLcItYVvoWeJC6emjTdQBNdkOyxrSYK4Dtvnzl7Y030wkRbGb7i0_FSBj95mtIZIWg1tMf5ltrHKqhh5FcK6SfuNbe2Y69bmGDYXHk0Ha8T29MUMR86Udbak1hEIcFFPVMgHWV7f7N2qio4SYw77kaSku-LaedAbXemoKnrhGc3n0Qk9_JzfJgTtX-ZtKGIXIoSBhsvJgHWELjahlsFWxo3WquBDJMQHEeamYiJ_TNg32ODwzfA8rHFGORDdcyzon4XfaiqNoeEzczWNxInO42WM3pUVUG5a6XN4OCMdUw163QbUFoPos2xEt3fMjB6D-6LaaAIRgORV24QLjkOw
JWT decoded with public key:
{
"jti": "d8fe773e-e311-11ef-8719-9a6556d6d115",
"iss": "https://www.cardlytics.com",
"sub": "Publisher",
"iat": 1740546392.61085,
"exp": 1740546692.61085,
"kid": "Key_v1"
}
JWT Claims and Key Storage
-
Signed using a signing-private-key (per FI/Bank) and banks will validate using a signing-public-key provided by CDLX. (Private key stored in AWS Secrets Manager)
-
For each webhook request, a new JWT will be created.
JWT Claim Definitions
Claim | Description |
---|---|
jti | Randomly generated unique ID |
iat | Time the JWT is generated |
iss | Issuer — https://www.cardlytics.com |
sub | Subject — Bank’s Name |
exp | Expiration Time — 10 minutes from creation |
kid | ID of the key used to sign the JWT |
Request Body Verification
We've included a SHA256withRSA hash of the request payload as an additional authentication layer.
You can hash the payload using SHA256 without SALT to verify integrity. The result should match the value in the request header.
The hash is signed using SHA256withRSA, the same method and key used to sign JWTs. Validate this signature using the public key you have.
X-CDLX-HASH: kid="Key_v1", hash="{encoded-hash}"
Request Payload Example
(Payload structure may differ from Redemption Feed)
{
"event": "REDEMPTION_CONFIRMED",
"eventId": "48533af7-bb5c-4e67-8024-1b14de064af9",
"eventTimestamp": "2025-01-29T18:46:42.838215856Z",
"redemptions": [
{
"redemptionId": "107605711",
"adId": "1000076078",
"amount": "132",
"date": "2025-01-28 00:00:00",
"sourceCustomerId": "4yHxFpbfqC9UeQmZUPqLCwX3hE4NU2Ces3Uf6yzt3sxX5Qytodp6mgtTyrFSYikhipw8X14fKWr36WpZowPa3HJtXZf8",
"sourceAccountId": "3wD1Mt2rHeugQUTVPFN55xZ3p8LCzbJ9jGa826zgHTUyiEygFcc7bVs58iNf1mxY746Ppt8CHfeUFy9HLJHh55no91KRJgnu7uLWsjgWqPaTH9c5CXpL",
"redeemingTransactionAmount": "2645",
"transactionId": "AitWYMLtbXms3UZsPc4XAbAAzvsdGyvRzH6PRkxYRRQ1RnnpiLeQNMVGMtWSdpjWytBF7gx1eueXPKoZbxUQugyAyJNSvzxEaCuZau8EZNtP",
"rewardSettlementRunDate": "2025-01-29T18:46:42.711700924Z"
}
]
}
Key Rotation Process
The key ID maps back to the public key on your side.
During key rotation, you will maintain two public keys:
- The current key
- The new key being introduced
Initially, the key ID will map to the current public key. When rotation occurs, requests will begin using the new key ID. Since you’ll have both keys during the transition, you can switch to the new key without downtime.
This process repeats for every rotation.
Webhook Implementation Requirements
From Publisher
- Test Webhook Endpoint
- Prod Webhook Endpoint
- Whitelist IP Addresses
- Extract public key from mTLS certs
From CDLX
- Share IP Addresses with Publisher
Contact your designated Cardlytics implementation consultant for more information.
Supported RTM Events
Redemption Notification
Property | Type | Description |
---|---|---|
event | RealtimeMessagingEventType | Type of RTM event |
eventId | string | Unique uuid associated with the RTM event |
eventTimestamp | string | ISO 8601 timestamp representing when the redemption event occurred |
redemptions | Redemption[] | List of redemptions |
Example
The following example represents a confirmed redemption event. It describes a webhook payload for a successful redemption processing after a cleared transaction.
{
"event": "REDEMPTION_CONFIRMED",
"eventId": "380052b4-3a64-4952-b640-ba696eb9f44b",
"eventTimestamp": "2023-04-29T11:06:55.000Z",
"redemptions": [
{
"redemptionId": "992745",
"adId": "123",
"amount": 5.00,
"redemptionDate": "2023-03-21T12:58:34Z",
"sourceCustomerId": "609a180c-c896-4ccb-8ef6-8b24fd6ef32b",
"sourceAccountId": "388836454",
"redeemingTransactionAmount": 34.46,
"transactionId": "929994552",
"rewardSettlementRunDate": "2023-03-23T10:44:23Z"
}
]
}
Redemption Notification -- Pending
Example
The example shows the payload for a realtime message after an eligible authenticated transaction.
{
"event":"REDEMPTION_PENDING",
"eventId":"0e486fb7-176b-45bc-9263-aadbc332400f",
"eventTimestamp":"2024-09-10T08:26:01.693504371Z",
"redemptions":[
{
"redemptionId":"0e486fb7-176b-45bc-9263-aadbc332400f",
"adId":"1000061994",
"amount":"207",
"date":"2024-09-10T08:26:01.693504371Z",
"sourceCustomerId":"AZFFL6QfbPoBxYMghFLkZodo7VQSLx29ah8dzv9gQKjHMMwPNhHzjNhbh5FSTy7MZdiMb1ZwKYMfaNDJh43zwiN7tdG",
"sourceAccountId":"riiDHpQmwLxp3Xc1sytdJsmmBQkVxsaZn8yLkmjd2eofVGSJfbQvSqL52yX1rwRgErNPdFvCF4NFZUvw8AMHyD2kfSGYrYMs5iAbtFUirPav16gkBLSq",
"redeemingTransactionAmount":"4136",
"transactionId":"5x6KV26iSctZyuMCXUKNYmTi7Y4g3X7sy1TRkiUiG1Q5hxrDh57QFhzzLLwPJoG6zQwrgau87Wa24wtzcNvr8bNtSJFt2rHH1vZoMtf",
"rewardSettlementRunDate":null
}
]
}
Updated 4 days ago