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:
Event | Description |
---|---|
onQuerySubmit | When a user submits a question |
onAnswerGenerationCompleted | When an answer is fully generated |
onAnswerGenerationStop | When generation is manually stopped by the user |
onConversationReset | When the conversation is reset |
onFeedbackSubmit | When 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.
Fingerprinting for anonymous analytics
For anonymous users, you can enable fingerprinting to generate consistent identifiers:
<KapaProvider
integrationId="your-integration-id"
fingerprintingEnabled={true}
callbacks={{...}}
>
<YourApplication />
</KapaProvider>
When enabled, the SDK generates a browser fingerprint and use it as an anonymous identifier.
Privacy considerations
When implementing analytics:
- Consent: Ensure you have user consent for tracking, especially in regions covered by GDPR, CCPA, etc.
- PII: Be careful with personally identifiable information in questions and answers.
- Fingerprinting: Make sure your privacy policy mentions fingerprinting if you enable this feature.
- 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.