Extended API Integration

Kard’s Extended API feature enhances our existing rewards endpoints with dynamic, per-user offer data. By requesting UI components through the supportedComponents query parameter, you can surface richer offer experiences to your end users including dynamic descriptions, call-to-action buttons, and contextual tags without building custom logic to interpret raw offer data.

This guide covers how to request and render extended offer fields from the Get Offers by User and Get Locations by User endpoints.

Key Concepts

Supported Components

The Extended API uses a component-based model to deliver dynamic offer data. You tell Kard which UI components your app supports, and the API returns the relevant data for each offer.

ComponentDescriptionExample Use Case
shortDescriptionA brief, dynamic description of the offer suitable for list views”Multi-use”, “Single use”
longDescriptionA detailed description suitable for offer detail pages”Use your linked card on qualifying purchases to redeem multiple times.”
ctaA call-to-action button with text, style, and an optional action URL”Tap to boost” button
tagsContextual labels for the offer in list/browse views["New"], ["5 days left"]
detailTagsContextual labels for the offer detail page["Activated"]
baseRewardA formatted reward string ready for display in your UI"5% cash back"

Coming soon: Offer activations. Some offers will require explicit user action to redeem such as tapping a call-to-action button to boost, renew, or activate an offer. Integrating with the cta component is strongly recommended to ensure the best end-user experience, making it clear to your users what actions are available and driving engagement with offers. Building support for this now gives you a head start so you’re ready when these offers go live.

How Components Are Returned

The components included in the response depend on what you request via the supportedComponents query parameter:

  • All components (shortDescription, longDescription, cta, tags, detailTags, baseReward): The full experience. Provides dynamic descriptions, call-to-action buttons, contextual tags, and a formatted reward string for both list and detail views. Best for apps that support interactive elements.
  • Description + call-to-action components (shortDescription, longDescription, cta): Provides dynamic descriptions that reflect per-user offer state along with a call-to-action button for actions like offer activation or offer boosts. Best for apps that want actionable offers without rendering tag-based UI.
  • Description-only components (shortDescription, longDescription): Provides dynamic descriptions without interactive elements. Best for apps that cannot render buttons or tags. In this case, Kard uses a VIEW event on the offer as the activation signal. When a user views an offer detail page, you fire a VIEW attribution event. After the event, re-fetch the offer to display the updated descriptions reflecting the new user state.

You can request any combination of components. Kard evaluates each offer independently and returns the appropriate data based on what you request.

Implementation

Step 1: Add the supportedComponents Query Parameter

Append the supportedComponents query parameter to your existing Get Offers by User or Get Locations by User requests. Use repeated parameters for multiple component types.

Get Offers by User with all components:

GET /v2/issuers/{{organizationId}}/users/{{userId}}/offers?supportedComponents=shortDescription&supportedComponents=longDescription&supportedComponents=cta&supportedComponents=tags&supportedComponents=detailTags&supportedComponents=baseReward

Get Offers by User with description + call-to-action components:

GET /v2/issuers/{{organizationId}}/users/{{userId}}/offers?supportedComponents=longDescription&supportedComponents=shortDescription&supportedComponents=cta

Get Locations by User with all components:

GET /v2/issuers/{{organizationId}}/users/{{userId}}/locations?include=offers&supportedComponents=shortDescription&supportedComponents=longDescription&supportedComponents=cta&supportedComponents=tags&supportedComponents=detailTags&supportedComponents=baseReward

Get Locations by User with description + call-to-action components:

GET /v2/issuers/{{organizationId}}/users/{{userId}}/locations?include=offers&supportedComponents=longDescription&supportedComponents=shortDescription&supportedComponents=cta

Get Offers by User with description-only components:

GET /v2/issuers/{{organizationId}}/users/{{userId}}/offers?supportedComponents=shortDescription&supportedComponents=longDescription

Get Locations by User with description-only components:

GET /v2/issuers/{{organizationId}}/users/{{userId}}/locations?include=offers&supportedComponents=shortDescription&supportedComponents=longDescription

For Get Locations by User, you must include include=offers in the query to receive offer data with components.

Step 2: Parse the components Object

When supportedComponents is provided and an offer is eligible for extended data, the response includes a components object within the offer attributes.

Example Response with all components (offer not yet activated):

1{
2 "data": [
3 {
4 "type": "standardOffer",
5 "id": "5e27318c9b346f00087fbb5c",
6 "attributes": {
7 "name": "Worlds Greatest Chicken",
8 "userReward": {
9 "type": "PERCENT",
10 "value": 5.7
11 },
12 "purchaseChannel": ["INSTORE"],
13 "startDate": "2024-11-17T05:00:00Z",
14 "expirationDate": "2025-03-17T05:00:00Z",
15 "terms": "Worlds Greatest Chicken offers are only available within US Locations.",
16 "isTargeted": true,
17 "assets": [
18 {
19 "type": "IMG_VIEW",
20 "url": "https://attribution.getkard.com/image.jpg?token=valid.signed.jwt",
21 "alt": "Worlds Greatest Chicken Logo Image"
22 }
23 ],
24 "components": {
25 "shortDescription": "Multi-use",
26 "longDescription": "Use your linked card on qualifying purchases to redeem multiple times.",
27 "cta": {
28 "buttonText": "Tap to activate",
29 "buttonStyle": "PRIMARY",
30 "action": {
31 "url": "/v2/issuers/{{organizationId}}/users/{{userId}}/offers/5e27318c9b346f00087fbb5c/activate",
32 "method": "POST"
33 }
34 },
35 "tags": [],
36 "detailTags": ["Activated"],
37 "baseReward": "5.7% cash back"
38 }
39 },
40 "relationships": {
41 "category": {
42 "data": [
43 { "type": "category", "id": "65920081b524d126068de24a" }
44 ]
45 }
46 }
47 }
48 ],
49 "links": {
50 "self": "/v2/issuers/{{organizationId}}/users/{{userId}}/offers?supportedComponents=shortDescription&supportedComponents=longDescription&supportedComponents=cta&supportedComponents=tags&supportedComponents=detailTags&supportedComponents=baseReward",
51 "prev": null,
52 "next": null
53 },
54 "included": [
55 {
56 "type": "category",
57 "id": "65920081b524d126068de24a",
58 "attributes": { "name": "Food & Beverage" }
59 }
60 ]
61}

Example Response with all components (offer already activated):

1"components": {
2 "shortDescription": "Multi-use",
3 "longDescription": "Use your linked card on qualifying purchases to redeem multiple times.",
4 "tags": [],
5 "detailTags": ["Activated"],
6 "baseReward": "5.7% cash back"
7}

Note that when the offer is already activated, the cta component is not included in the response.

Step 3: Render Components in Your UI

How you render the components depends on which ones you requested:

If you requested all components (shortDescription, longDescription, cta, tags, detailTags, and baseReward)

  1. Display shortDescription on offer cards in list/browse views
  2. Display longDescription on the offer detail page
  3. If cta is present and buttonStyle is PRIMARY, display the call-to-action button using buttonText — when tapped, call the URL in cta.action.url using the specified cta.action.method (see Step 4a)
  4. If cta is absent, the offer has already been activated — hide the call-to-action button
  5. Render tags as overlays or badges on the offer card in list/browse views (may be empty)
  6. Render detailTags as labels on the offer detail page
  7. Display baseReward as the formatted reward amount on the offer card (e.g., “5.7% cash back”)

All components, offer not activated:

All components, offer not activated

All components, offer is activated:

All components, offer activated

If you requested a subset of components (shortDescription, longDescription, and cta):

  1. Display longDescription on the offer detail page
  2. Display shortDescription on offer cards in list views
  3. If cta is present and buttonStyle is PRIMARY, display the call-to-action button using buttonText — when tapped, call the URL in cta.action.url using the specified cta.action.method (see Step 4a)
  4. If cta is absent, the offer has already been activated — hide the call-to-action button

Description + call-to-action components, offer not activated:

Description and CTA components, offer not activated

Description + call-to-action components, offer is activated:

Description and CTA components, offer activated

If you requested description-only components (shortDescription and longDescription):

This approach is for issuers that cannot render interactive call-to-action buttons. Instead of using a call-to-action button to activate or boost offers, the VIEW event serves as the activation signal.

  1. Display shortDescription on offer cards in list/browse views
  2. Display longDescription on the offer detail page
  3. When a user navigates to the offer detail page, fire a VIEW attribution event (see Step 4b)
  4. After the VIEW event, re-fetch the offer to get updated descriptions that reflect the new user state (e.g., descriptions change from “Tap to activate” to “Activated”)
  5. Re-render the offer with the updated shortDescription and longDescription

Important: Without a call-to-action button, the user has no explicit activation action. The VIEW event acts as a proxy for activation. You must re-fetch and re-render the offer after firing the VIEW event to display the updated state to the user.

Step 4a: Handle Call-To-Action Events

Activations are an upcoming feature. Some offers will require user action before the offer can be redeemed. Supporting the call-to-action flow is key to delivering a clear, intuitive experience for your end users by surfacing actionable next steps directly in the UI. Integrating now means you’ll be ready to support these offers as soon as they launch.

When a user taps a PRIMARY call-to-action button, call the activation endpoint provided in cta.action:

POST /v2/issuers/{{organizationId}}/users/{{userId}}/offers/{{offerId}}/activate

You can include supportedComponents and include=offer as query parameters to receive the updated offer in the response:

POST /v2/issuers/{{organizationId}}/users/{{userId}}/offers/{{offerId}}/activate?supportedComponents=shortDescription&supportedComponents=longDescription&supportedComponents=cta&supportedComponents=tags&supportedComponents=detailTags&supportedComponents=baseReward&include=offer

Response (201 Created):

1{
2 "data": {
3 "type": "offerAttribution",
4 "id": "attribution-event-id",
5 "attributes": {
6 "entityId": "5e27318c9b346f00087fbb5c",
7 "eventCode": "ACTIVATE",
8 "medium": "CTA",
9 "eventDate": "2025-01-07T16:30:00Z"
10 }
11 },
12 "included": [
13 {
14 "type": "standardOffer",
15 "id": "5e27318c9b346f00087fbb5c",
16 "attributes": {
17 "name": "Worlds Greatest Chicken",
18 "userReward": { "type": "PERCENT", "value": 5.7 },
19 "components": {
20 "shortDescription": "Multi-use",
21 "longDescription": "Use your linked card on qualifying purchases to redeem multiple times.",
22 "tags": [],
23 "detailTags": ["Activated"],
24 "baseReward": "5.7% cash back"
25 }
26 }
27 }
28 ]
29}

Use the updated offer from included to immediately refresh your UI without re-fetching the full offer list.

Step 4b: Handle VIEW Event Activation (Description-Only)

If you are only using shortDescription and longDescription (no cta), use the VIEW attribution event to signal that a user has engaged with an offer. This acts as the activation trigger.

When a user opens an offer detail page, fire a VIEW event:

POST /v2/issuers/{{organizationId}}/users/{{userId}}/offers/{{offerId}}/view

After a successful VIEW event, re-fetch the offer with your supported components to get the updated descriptions:

GET /v2/issuers/{{organizationId}}/users/{{userId}}/offers?supportedComponents=shortDescription&supportedComponents=longDescription

The descriptions will now reflect the updated user state:

1"components": {
2 "shortDescription": "Activated",
3 "longDescription": "Activated"
4}

Re-render the offer detail page with the updated longDescription, and update the offer card with the new shortDescription in your list views.

We recommend integrating with call-to-action components when possible. The call-to-action flow gives users a clear, explicit action to activate and boost offers and provides a better user experience than the implicit VIEW event approach.

Component Reference

components Object

FieldTypeDescription
shortDescriptionstring (optional)Brief dynamic description for list/browse views
longDescriptionstring (optional)Detailed dynamic description for offer detail pages
ctaobject (optional)Call-to-action button configuration
tagsstring[] (optional)Contextual labels for list/browse views
detailTagsstring[] (optional)Contextual labels for offer detail pages
baseRewardstring (optional)Formatted reward string for display (e.g., “5.7% cash back” or “$2.00 cash back”)

cta Object

FieldTypeDescription
buttonTextstringText to display on the button (e.g., “Tap to activate”)
buttonStyleenumPRIMARY (actionable). The cta component is omitted entirely once the offer is activated.
actionobjectContains the URL and method to call when the button is tapped
action.urlstringAPI endpoint to call when the button is tapped
action.methodstringHTTP method to use (e.g., POST)

Important Notes

Component availability is per-offer. Different offers in the same response may return different components depending on their configuration.

The components object is additive. Existing fields like name, userReward, terms, and assets are always returned regardless of whether you request components.

Best Practices

  • Always check for the presence of components before rendering. Not every offer will include it — your UI should gracefully fall back to standard offer fields.
  • Use cta.action exactly as provided. The URL and method are pre-configured by Kard. Do not modify the URL path or method.
  • Render call-to-action state changes immediately. After a successful activation call, use the updated offer from the response included array to update your UI without waiting for a full list refresh.
  • Choose components based on your UI capabilities. If you cannot render interactive buttons, request shortDescription and longDescription instead of cta, tags, and detailTags.
  • Request only the components you support. Avoid requesting components you don’t intend to render.
  • Handle the absence of cta after activation. When an offer has been activated, the cta component is not included in the response. Your UI should hide the call-to-action button when cta is absent.
  • Do not cache component data across sessions. Component values like tags and CTA state are dynamic and may change between requests.