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

ClaimDescription
jtiRandomly generated unique ID
iatTime the JWT is generated
issIssuer — https://www.cardlytics.com
subSubject — Bank’s Name
expExpiration Time — 10 minutes from creation
kidID 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

PropertyTypeDescription
eventRealtimeMessagingEventTypeType of RTM event
eventIdstringUnique uuid associated with the RTM event
eventTimestampstringISO 8601 timestamp representing when the redemption event occurred
redemptionsRedemption[]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
      }
   ]
}