Skip to main content

Event tracking and analytics

The Kapa SDK provides event tracking capabilities through callback functions. This allows you to monitor user interactions with the AI and integrate with your analytics systems.

Available events​

The SDK emits events at key points in the user journey:

EventDescription
onQuerySubmitWhen a user submits a question
onAnswerGenerationCompletedWhen an answer is fully generated
onAnswerGenerationStopWhen generation is manually stopped by the user
onConversationResetWhen the conversation is reset
onFeedbackSubmitWhen a user provides feedback on an answer

Setting up callbacks​

Configure event callbacks when setting up the KapaProvider:

import { KapaProvider } from "@kapaai/react-sdk";

function App() {
return (
<KapaProvider
integrationId="your-integration-id"
callbacks={{
askAI: {
onQuerySubmit: (data) => {
console.log("Question asked:", data.question);
// Send to your analytics service
},
onAnswerGenerationCompleted: (data) => {
console.log("Answer generated:", {
questionId: data.questionAnswerId,
question: data.question,
answer: data.answer,
});
},
onFeedbackSubmit: (data) => {
console.log("Feedback submitted:", {
questionId: data.questionAnswerId,
reaction: data.reaction,
comment: data.comment,
});
},
},
}}
>
<YourApplication />
</KapaProvider>
);
}

Callback payloads​

Each event callback receives a data object with relevant information:

onQuerySubmit​

interface QuerySubmitPayload {
// The question text
question: string;

// Current thread ID (null for first message)
threadId: string | null;

// Full conversation history
conversation: {
questionAnswerId: string;
question: string;
answer: string;
}[];
}

onAnswerGenerationCompleted​

interface AnswerGenerationCompletedPayload {
// The question text
question: string;

// The generated answer
answer: string;

// ID of the QA pair
questionAnswerId: string;

// Current thread ID
threadId: string;

// Full conversation history
conversation: {
questionAnswerId: string;
question: string;
answer: string;
}[];
}

onAnswerGenerationStop​

interface AnswerGenerationStopPayload {
// The question text
question: string;

// Current thread ID
threadId: string | null;

// Full conversation history
conversation: {
questionAnswerId: string;
question: string;
answer: string;
}[];
}

onConversationReset​

interface ConversationResetPayload {
// Current thread ID
threadId: string | null;

// Full conversation history (before reset)
conversation: {
questionAnswerId: string;
question: string;
answer: string;
}[];
}

onFeedbackSubmit​

interface FeedbackSubmitPayload {
// ID of the feedback
feedbackId: string;

// ID of the QA pair
questionAnswerId: string;

// User's reaction
reaction: "upvote" | "downvote";

// Optional user comment
comment?: {
incorrect?: boolean;
irrelevant?: boolean;
unaddressed?: boolean;
issue?: string;
};

// The question text
question: string;

// The answer text
answer: string;

// Current thread ID
threadId: string | null;

// Full conversation history
conversation: {
questionAnswerId: string;
question: string;
answer: string;
}[];
}

Integration examples​

Google Analytics​

import { KapaProvider } from "@kapaai/react-sdk";

function App() {
return (
<KapaProvider
integrationId="your-integration-id"
callbacks={{
askAI: {
onQuerySubmit: (data) => {
// Google Analytics 4 event
window.gtag("event", "ask_question", {
question: data.question,
thread_id: data.threadId,
});
},
onAnswerGenerationCompleted: (data) => {
window.gtag("event", "answer_generated", {
question_id: data.questionAnswerId,
answer_length: data.answer.length,
});
},
onFeedbackSubmit: (data) => {
window.gtag("event", "feedback_submitted", {
question_id: data.questionAnswerId,
reaction: data.reaction,
});
},
},
}}
>
<YourApplication />
</KapaProvider>
);
}

Segment​

import { KapaProvider } from "@kapaai/react-sdk";

function App() {
return (
<KapaProvider
integrationId="your-integration-id"
callbacks={{
askAI: {
onQuerySubmit: (data) => {
window.analytics.track("AI Question Asked", {
question: data.question,
threadId: data.threadId,
});
},
onAnswerGenerationCompleted: (data) => {
window.analytics.track("AI Answer Generated", {
questionId: data.questionAnswerId,
question: data.question,
answerLength: data.answer.length,
});
},
onFeedbackSubmit: (data) => {
window.analytics.track("AI Feedback Submitted", {
questionId: data.questionAnswerId,
reaction: data.reaction,
hasComment: !!data.comment,
});
},
},
}}
>
<YourApplication />
</KapaProvider>
);
}

Custom backend​

import { KapaProvider } from "@kapaai/react-sdk";

function App() {
const logEvent = async (eventName, eventData) => {
try {
await fetch("https://your-analytics-api.example.com/events", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
event: eventName,
timestamp: new Date().toISOString(),
userId: getCurrentUserId(), // Your user ID function
data: eventData,
}),
});
} catch (err) {
console.error("Failed to log event:", err);
}
};

return (
<KapaProvider
integrationId="your-integration-id"
callbacks={{
askAI: {
onQuerySubmit: (data) => {
logEvent("ai_question_asked", {
question: data.question,
threadId: data.threadId,
});
},
onAnswerGenerationCompleted: (data) => {
logEvent("ai_answer_generated", {
questionId: data.questionAnswerId,
question: data.question,
answer: data.answer,
});
},
},
}}
>
<YourApplication />
</KapaProvider>
);
}

User identification​

For better analytics, you can provide user identification data by configuring the window.kapaSettings object:

// Set this before the KapaProvider is mounted
window.kapaSettings = {
user: {
email: "user@example.com",
uniqueClientId: "user-123",
metadata: {
companyName: "Acme Corp",
firstName: "Jane",
lastName: "Doe",
},
},
};

This information is sent along with queries to the Kapa backend and can be used for user-specific analytics.

Anonymous user tracking​

You can enable anonymous user tracking to generate identifiers for unique users:

<KapaProvider
integrationId="your-integration-id"
userTrackingMode="cookie"
callbacks={{...}}
>
<YourApplication />
</KapaProvider>

When enabled, the SDK generates a unique ID and uses it to identify unique users anonymously.

See User tracking mode for details.

Privacy considerations​

When implementing analytics:

  1. Consent: Ensure you have user consent for tracking, especially in regions covered by GDPR, CCPA, etc.
  2. PII: Be careful with personally identifiable information in questions and answers.
  3. User tracking: Make sure your privacy policy mentions anonymous user tracking if you enable this feature.
  4. Data Minimization: Only store what you need for your analytical purposes.

Debugging events​

During development, you can log all events to the console:

<KapaProvider
integrationId="your-integration-id"
callbacks={{
askAI: {
onQuerySubmit: (data) => console.log("onQuerySubmit", data),
onAnswerGenerationCompleted: (data) =>
console.log("onAnswerGenerationCompleted", data),
onAnswerGenerationStop: (data) =>
console.log("onAnswerGenerationStop", data),
onConversationReset: (data) => console.log("onConversationReset", data),
onFeedbackSubmit: (data) => console.log("onFeedbackSubmit", data),
},
}}
>
<YourApplication />
</KapaProvider>

This helps verify that events are firing correctly and contain the expected data.