Getting Started - Core
Core Content Block is the necessary content block for dealing with basic building blocks of your application. Core content block provides the core functionality for the Kenkai SDK in order to set up the SDK and also helps with the nudge listening mechanism.
Core content block mainly focus on events related to app navigation of your application, such as events related to app -> app opening, app closing or moving to background. Also for the screen related events, how much time a user spends on a screen and also some basic functional events as well such as login, media related or search related events.
To use the SDK, Core is mandatory to include as it contains the elements regarding the basic app navigation and workflow including nudges. Moreover, all the modules require the core to be integrated to successfully log the events.
To initialise the core SDK, you can jump over to Getting Started Section
As per the SDK structure, content blocks are further divided into 2 main categories: Ingest Events and Catalog Events.
- Ingest Events helps with time sensitive elements such as when an event is happening.
- Catalog/Dimension Events helps with static content that provide details about the elements in the events.
To get into more details, You can view both Ingest events and Catalog Events for Core Module.
Explore Customizations
This section provides detailed information on how to customize and interact with the Kenkai SDK's core features. You will find guides on understanding the log format, handling action callbacks, managing in-app messages, and fetching custom or bulk actions to tailor the SDK's behavior to your application's needs.
| Section Name | Description |
|---|---|
| Main Log Format | Understanding the complete log object sent from the SDK |
| Action CTA Event | Callback for opening pages based on the CTA provided in the SDK actions/nudges |
| Manage InAppMessage Actions | Manage the visibility for Auto showing inApp Messages in the app |
| Fetch Custom Actions | Fetch Custom Actions such as UI components based interventions i.e. recommendation list |
| Fetch Bulk Actions | Fetch Actions in bulk for all the users, ideal for sending actions using external platforms such as WhatsApp or other messaging platforms |
Main Log Format
Kenkai SDK automatically starts tracking user data (e.g., OS version, device IDs, online/offline status) and engagement with the basic setup above. This data can be stored on the device and uploaded in batches to reduce network and power usage, and to increase the likelihood of successful uploads while you can also upload the events as soon as they happen. The upload is done when the user device session ends. SDK also starts tracking user sessions with this basic setup.
This enables you to gain in-depth insights into user interactions across partner's app. You can also leverage this data to segment users, personalize messages and configure campaign targeting.
We have several predefined actions that users can perform while interacting with partner's app. These actions are referred to as System Events that help in tracking elements on partner's app with user interaction. Some of these events are automated so that partner's don’t have to spend time integrating them.
Below is the Main Body Log Format and its sections that are dependent on it.
Main Log Body Format:
| Param | Usability | Format | Description |
|---|---|---|---|
| id: | REQUIRED | STRING | Unique id for a user, provided by the partner |
| tz | REQUIRED | STRING (ISO 8601 format - Timezone) | Timezone, auto-provided by SDK |
| internal | REQUIRED | InternalObject | Timezone, auto-provided by SDK |
| data | REQUIRED | ARRAY DataObject | Contains the logs that happened in the session, more details follow. |
Internal Info Object Format:
| Param | Usability | Format | Description |
|---|---|---|---|
| s_id: | REQUIRED | STRING <u_id>_startTimeInMillis_endTimeInMillis) | Unique id for each session, autogenerated by SDK. endTimeInMillis will be 0 for immediate events |
| sdk | REQUIRED | STRING <os_name> | Version of sdk in use, auto-provided by the SDK. |
| app_id | REQUIRED | STRING | Unique id for the app using which the app is released on the play stores/website url. |
| app_version | REQUIRED | STRING | Complete version name for the app : <major_version>.<minor_version>.<patch_version> (<version_code>) |
| device_id | REQUIRED | STRING | Unique Id for the device being used, auto-provided by SDK. |
| device_os | REQUIRED | STRING | OS name of the phone being used, auto-provided by SDK. |
Data Object Format:
| Param | Usability | Enum | Format | Description |
|---|---|---|---|---|
| time | REQUIRED | -- | STRING (ISO 8601 format) | Timestamp (including milliseconds) with timezone when event is triggered, auto-provided by SDK. |
| __ol | REQUIRED | -- | BOOLEAN | Online status of the device when the event was triggered. |
| name | REQUIRED | Event Name | STRING | Type of log/event being triggered. |
| property | REQUIRED | -- | STRING | Top level property value in the event. |
| ctx | REQUIRED | -- | OBJECT | A free form <Key-Value> schema depending on the value of type, Value should be of primitive type. |
Schema Overview of the Whole Object
{
"id": "user123",
"tz": "+02:00",
"internal": {
"s_id": "user123_1674728022000_1674728030000",
"sdk": "android/0.0.1",
"a_id": "io.kenkai.android.sdk",
"a_ver": "0.0.8 (1)",
"d_id": "91aebf68ce6140dc",
"os": "android"
},
"data": [
{
"time": "2025-10-02 15:04:05.122",
"__ol": true,
"name": "app",
"property": "open",
"ctx": {
"action": "open",
"start_time": 229
}
},
{
"time": "2025-10-02 15:04:06.144",
"name": "page",
"__ol": true,
"property": "Page Title",
"ctx": {
"title": "Page Title",
"path": "some_path.inner_path",
"render_time": 300
}
}
]
}
Action CTA Event
Recommendations based actions provide payload in the response, which can be used to trigger the CTA event. The CTA event can be to open a certain page in the app or to perform a certain action such as adding an item to the cart directly.
This is a callback event, you need to process the response based on your app architecture and handle the action accordingly.
Overview
| Param | Format | Description |
|---|---|---|
| cta_type | STRING | Action to be performed as a part of the recommendation - redirect/add-to_cart |
| cta_id | STRING | id of the product being recommended. |
Usage
- Android (Java/Kotlin)
- iOS (Swift)
- React Native (JS/TS)
- Web Application (JS/TS)
class MyApplication : Application(), LifecycleEventObserver, ActionOnClickInterface {
override fun onCreate() {
super.onCreate()
ActionOnClickObject.actionOnClickInterface = this
}
override fun onActionOpened(actionAttributes : Map<String, String>) {
Log.d("Notification Opened", "Notification Opened: ${actionAttributes["cta_type"]} \n ${actionAttributes["cta_id"]} \n $actionAttributes")
Toast.makeText(this,
"Notification Opened\", \"Notification Opened: ${actionAttributes["cta_type"]} \\n ${actionAttributes["cta_id"]} \\n $actionAttributes", Toast.LENGTH_LONG).show()
}
}
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
ActionOnClickObject.actionOnClickInterface = { actionAttrs in
// Define your logic here
let cta = actionAttrs?["cta_id"]
let itemID = actionAttrs?["cta_id"]
print(actionAttrs ?? "")
let actionItems = "\(cta ?? "null")||\(itemID ?? "null")"
print(actionItems) // Just for example, you can use this data as needed
}
}
}
// in App.tsx
const callback = (data: NudgeCallBack) => {
console.log('Received data from SDK:', data);
Alert.alert('Data from notif callback: ', JSON.stringify(data));
};
CFCore.getNudgeResponse(callback);
// in App.TSX
CfLog.getSDKInstance().on(CfLogEvents.ActionNudge, actionAttributes => {
console.log("ActionNudge received: ", actionAttributes);
const type = actionAttributes.cta_type;
if (type === CfLogEventType.Redirect) {
console.log("Redirect in this app");
} else if (type === CfLogEventType.AddToCart) {
console.log("Add-to-cart in this app");
} else {
console.log("received unknown event type: ", type);
}
});
Manage InAppMessage Actions
To show in-app messages on the screen of your choice, you can disable the auto show from the SDK initialisation as:
- Android (Java/Kotlin)
- iOS (Swift)
- React Native (JS/TS)
- Web Application (JS/TS)
CFLog.Builder()
.init(this) // pass in the context
...
.setAutoShowInAppMessage(autoShowInAppMessage = false) // use this and set the autoShowInAppMessage to false
...
.build()
then in your activity where you want to show the in-app message, you can show the nudge by using:
CFCoreEvent.showInAppMessage(ActionScreenType.Cart.toString()) // ActionScreenType is an enum provided in the SDK
CFLogBuilder()
...
.setAutoShowInAppMessages(showInAppMessage: false) // use this and set the showInAppMessage to false
...
.build()
then in your screens where you want to show the in-app message, you can show the action by using:
CFCoreEvent.shared.showInAppMessage(actionScreenType: .Cart) // actionScreenType is an enum provided in the SDK
To initialise Self Managed InApp messages, you need to follow the same steps in Android and iOS for setting up the flag. For calling the function individual screens/components you need to use the code bwlow:
CFCore.init({
...
isInAppMessagesAutoDisplay: false
});
then in your screens where you want to show the in-app message, you can show the action by using:
CFCore.showInAppMessage(ActionScreenType.Cart);
// in App.js
CfLog.createSDKInstance(
'<your-sdk-key>',
{
activateNudgeMechanism: true,
selfManagedNudges: true // use this and set the showInAppNudge to true
}
)
then in your screens/components where you want to show the in-app message, you can show the nudge by using:
CfLog.getSDKInstance().fetchInAppMessageActionForScreen(ActionScreenType.Cart); // NudgeScreenType is an enum provided in the SDK
Fetch Custom Actions
To show custom actions, you can call the following function:
- Android (Java/Kotlin)
- iOS (Swift)
- React Native (JS/TS)
- Web Application (JS/TS)
CFCoreEvent.fetchActions(
invActionType = InvActionType.Custom,
actionRenderMethodType = ActionRenderMethodType.InAppComponent,
deliveryMode = ActionDeliveryMode.OneOff,
actionAttr = mapOf( "hello" to "world" ),
onResult = {
Toast.makeText(this, "CFCoreEvent.fetchActions", Toast.LENGTH_SHORT).show()
}
)
CFCoreEvent.shared.fetchActions(
invActionType: .UIComponent,
actionRenderMethodType: .InAppComponent,
deliveryMode: .OneOff,
actionAttr: nil,
onResult: { items in
print("✅ Received actions:", items)
}
)
CFCore.fetchActions(
InvActionType.UIComponent,
ActionRenderMethodType.inAppComponent,
ActionDeliveryMode.Cached,
{ screen: 'home' }
).then(
(response) => {
console.log('Fetched Actions:', response);
}
);
CfLog.getSDKInstance().fetchActions(
InvActionType.Custom,
ActionRenderMethodType.InAppMessage,
ActionDeliveryMode.OneOff, {},
(actions) => {
console.log("✅ Actions received:", actions);
}
)
Fetch Bulk Actions
Fetch Actions in bulk for all the users, ideal for sending actions using external platforms such as WhatsApp or other messaging platforms. You will get the array of the actions with user ids as you provided to the SDK, along with personlaised messages for them. By using this method, you are responsible for sending these actions/nudges to the users based on the method of your choice.
Bulk action fetch is only available in API use. SDK does not have this support and only works for individual user action fetch
// POST REQUEST
curl --location 'https://api.kenkai.io/v1/action/pull' \
--header 'authorization: Bearer {YOUR_KEY_HERE}' \
--header 'content-type: application/json' \
--header 'host: api.kenkai.io' \
--data '{"delivery_mode":"one-off","render_method":"generic_message","type":"message","user_id":"*"}'
Request Body Overview
| Param | Usability | Format | Enum Values | Description |
|---|---|---|---|---|
| user_id | REQUIRED | STRING | * | Should be * for fetching all avavailble actions/nudges based on the rest of the filters. Can also be the user_id provided to the SDK |
| type | REQUIRED | STRING | message, custom | Main type of the action |
| render_method | REQUIRED | STRING | push_notification, in_app_message, generic_message | Render Method for action based on type of the action |
| delivery_mode | REQUIRED | STRING | one-off, cached | Delivery Mode for the action. one-off are provided once only as the name suggests, but the cached are sent everytime unless they expire |
| attr | OPTIONAL | OBJECT | -- | To further filter the actions. Attributes are provided while creating an action |
Response Body Overview
{
"data": [
{
"user_id": "49",
// As provided to the SDK
"payload": {
"type": "message",
"render_method": "generic_message",
"delivery_mode": "one-off",
"content": {
"body": "Action Body here",
"title": "Action Title here"
},
"attr": { // JSON - MAP<STRING, STRING> based on the action
"some_key": "some_value"
},
"tags": [],
"internal": {
"inv_id": 107,
"action_id": 96,
"expired_at": "2026-01-14T01:00:00+01:00",
...
}
},
"error": null,
"queued_at": "2026-01-13T00:00:06.629933Z"
},
...
]
}