data-studio-sdk
v1.0.6
Published
TypeScript SDK for Data Studio
Maintainers
Readme
Data Studio SDK
A TypeScript SDK for tracking user interactions, sessions, and events in your application. The SDK automatically handles client creation, session management, and event tracking with seamless backend synchronization via AWS SQS.
Table of Contents
Installation
npm install data-studio-sdk
# or
yarn add data-studio-sdkQuick Start
import { DataStudioSDK } from "data-studio-sdk";
// Initialize the SDK with your API key
// Format: "tenantId@apiKey"
const sdk = new DataStudioSDK({
apiKey: "your-tenant-id@your-api-key",
});
// The SDK automatically creates a client on initialization
// Start a session
await sdk.startSession();
// Track events
await sdk.sendRatingEvent({
rating: 1,
max: 5,
raterId: "user-123",
});
// End session when done
await sdk.endSession();API Reference
Initialization
new DataStudioSDK(config: DataStudioSDKConfig)
Creates a new instance of the Data Studio SDK.
Parameters:
config.apiKey(string, required): API key in the format"apiKey"(e.g.,"123@1234-567-890")
Note: Your API key is available to copy from the Data Studio console.
Example:
const sdk = new DataStudioSDK({
apiKey: "your-api-key",
});Note: The SDK automatically:
- Fetches credentials from the API
- Initializes sync services (Client, Session, Event)
- Creates a client on initialization
Client Management
createClient(input?: ClientInput): Promise<Client>
Creates a new client. This is automatically called during SDK initialization, but you can call it manually if needed.
Parameters:
input(ClientInput, optional): Manual client configuration. If not provided, the SDK auto-detects browser information in browser environments.
Returns: Promise<Client>
Example:
// Browser environment - auto-detects info
const client = await sdk.createClient();
// Node.js/server environment - manual input
const client = await sdk.createClient({
clientType: "server",
ip: "192.168.1.1",
region: "us-east-1",
city: "New York",
timezone: "America/New_York",
});getClient(): Client | null
Returns the current client instance.
Returns: Client | null
Example:
const client = sdk.getClient();
if (client) {
console.log(`Client ID: ${client.id}`);
}closeClient(): Promise<void>
Closes the current client. This automatically ends any active session and syncs the updated client to the backend.
Example:
await sdk.closeClient();Session Management
startSession(input?: SessionInput): Promise<Session>
Starts a new session. A client must be created before starting a session.
Parameters:
input(SessionInput, optional): Session configurationuserId?: string- Optional user identifiercountry?: string- Country codedeviceType?: string- Device typereferrer?: string- Referrer URL
Returns: Promise<Session>
Example:
const session = await sdk.startSession({
userId: "user-123",
country: "US",
deviceType: "desktop",
referrer: "https://example.com",
});endSession(): Promise<void>
Ends the current active session. Calculates session duration and syncs to backend.
Example:
await sdk.endSession();getCurrentSession(): Session | null
Returns the current active session.
Returns: Session | null
Example:
const session = sdk.getCurrentSession();
if (session) {
console.log(`Session ID: ${session.id}, Status: ${session.status}`);
}Event Tracking
The SDK provides methods for tracking various types of events. All event methods require an active session.
Feedback & Quality Events
Helpful for experience analytics.
Rating Submitted
sendRatingEvent(event: RatingEvent): Promise<void>
Sends a rating submitted event.
Parameters:
event.rating(number, required): rating valueevent.max(number, required): Maximum rating valueevent.source(string, optional): Source of the ratingevent.raterId(string, optional): ID of the user providing the rating
Example:
await sdk.sendRatingEvent({
rating: 1,
max: 5,
source: "product-page",
raterId: "user-123",
});Feedback Submitted
sendFeedbackEvent(event: FeedbackEvent): Promise<void>
Sends a feedback submitted event.
Parameters:
event.text(string, required): Feedback textevent.category(string, optional): Feedback categoryevent.rating(number, optional): Associated rating valueevent.source(string, optional): Source of the feedback
Example:
await sdk.sendFeedbackEvent({
text: "Great product! Very satisfied with the quality.",
category: "product-quality",
rating: 5,
source: "feedback-form",
});Bug Reported
sendBugReportEvent(event: BugReportEvent): Promise<void>
Sends a bug reported event.
Parameters:
event.description(string, required): Bug descriptionevent.severity(string, optional): Bug severity level (e.g., "low", "medium", "high", "critical")event.stepsToReproduce(string, optional): Steps to reproduce the bugevent.component(string, optional): Affected component or area
Example:
await sdk.sendBugReportEvent({
description: "Button not responding on mobile devices",
severity: "high",
stepsToReproduce:
"1. Open app on mobile 2. Click submit button 3. Nothing happens",
component: "checkout-form",
});Survey Started / Completed
sendSurveyEvent(event: SurveyEvent): Promise<void>
Sends a survey started or completed event.
Parameters:
event.surveyId(string, required): Unique survey identifierevent.status("started" | "completed", required): Survey statusevent.questionCount(number, optional): Number of questions in the surveyevent.duration(number, optional): Duration in milliseconds
Example:
// Survey started
await sdk.sendSurveyEvent({
surveyId: "survey-123",
status: "started",
questionCount: 10,
});
// Survey completed
await sdk.sendSurveyEvent({
surveyId: "survey-123",
status: "completed",
questionCount: 10,
duration: 120000, // 2 minutes in milliseconds
});User Complaint Received
sendComplaintEvent(event: ComplaintEvent): Promise<void>
Sends a user complaint received event.
Parameters:
event.text(string, required): Complaint textevent.category(string, optional): Complaint categoryevent.priority(string, optional): Priority level (e.g., "low", "medium", "high", "urgent")event.status(string, optional): Complaint status (e.g., "new", "in-progress", "resolved")
Example:
await sdk.sendComplaintEvent({
text: "Unable to access my account after password reset",
category: "account-access",
priority: "high",
status: "new",
});Workflow & Business Process Events
Perfect for automation and internal tools.
sendWorkflowStartedEvent(event: WorkflowStartedEvent): Promise<void>
Sends a workflow started event.
Parameters:
event.workflowId(string, required): Unique workflow identifierevent.workflowName(string, optional): Name of the workflowevent.workflowType(string, optional): Type or category of the workflowevent.initiatorId(string, optional): ID of the user or system that initiated the workflow
Example:
await sdk.sendWorkflowStartedEvent({
workflowId: "workflow-123",
workflowName: "Order Processing",
workflowType: "e-commerce",
initiatorId: "user-456",
});sendWorkflowStepCompletedEvent(event: WorkflowStepCompletedEvent): Promise<void>
Sends a workflow step completed event.
Parameters:
event.workflowId(string, required): Unique workflow identifierevent.stepId(string, required): Unique step identifierevent.stepName(string, optional): Name of the completed stepevent.duration(number, optional): Duration of the step in millisecondsevent.status(string, optional): Status of the step completion
Example:
await sdk.sendWorkflowStepCompletedEvent({
workflowId: "workflow-123",
stepId: "step-456",
stepName: "Payment Processing",
duration: 2500,
status: "success",
});sendWorkflowErrorEvent(event: WorkflowErrorEvent): Promise<void>
Sends a workflow error event.
Parameters:
event.workflowId(string, required): Unique workflow identifierevent.stepId(string, optional): Step identifier where the error occurredevent.errorType(string, optional): Type or category of the errorevent.errorMessage(string, optional): Detailed error messageevent.errorCode(string, optional): Error code or identifierevent.severity(string, optional): Error severity level (e.g., "low", "medium", "high", "critical")
Example:
await sdk.sendWorkflowErrorEvent({
workflowId: "workflow-123",
stepId: "step-456",
errorType: "validation_error",
errorMessage: "Invalid payment method",
errorCode: "PAYMENT_001",
severity: "high",
});sendWorkflowAbortedEvent(event: WorkflowAbortedEvent): Promise<void>
Sends a workflow aborted event.
Parameters:
event.workflowId(string, required): Unique workflow identifierevent.reason(string, optional): Reason for aborting the workflowevent.abortedBy(string, optional): ID of the user or system that aborted the workflow
Example:
await sdk.sendWorkflowAbortedEvent({
workflowId: "workflow-123",
reason: "User cancelled operation",
abortedBy: "user-456",
});sendDocumentCreatedEvent(event: DocumentCreatedEvent): Promise<void>
Sends a document created event.
Parameters:
event.documentId(string, required): Unique document identifierevent.documentType(string, optional): Type of document (e.g., "invoice", "contract", "report")event.documentName(string, optional): Name of the documentevent.creatorId(string, optional): ID of the user who created the documentevent.templateId(string, optional): Template identifier if document was created from a template
Example:
await sdk.sendDocumentCreatedEvent({
documentId: "doc-123",
documentType: "invoice",
documentName: "Invoice #2024-001",
creatorId: "user-456",
templateId: "template-invoice-v2",
});sendDocumentApprovedEvent(event: DocumentApprovedEvent): Promise<void>
Sends a document approved event.
Parameters:
event.documentId(string, required): Unique document identifierevent.approverId(string, optional): ID of the user who approved the documentevent.reason(string, optional): Reason for approvalevent.comment(string, optional): Additional comments
Example:
await sdk.sendDocumentApprovedEvent({
documentId: "doc-123",
approverId: "user-789",
reason: "All requirements met",
comment: "Approved for production",
});sendDocumentRejectedEvent(event: DocumentRejectedEvent): Promise<void>
Sends a document rejected event.
Parameters:
event.documentId(string, required): Unique document identifierevent.approverId(string, optional): ID of the user who rejected the documentevent.reason(string, optional): Reason for rejectionevent.comment(string, optional): Additional comments or feedback
Example:
await sdk.sendDocumentRejectedEvent({
documentId: "doc-123",
approverId: "user-789",
reason: "Missing required information",
comment: "Please add customer signature before resubmission",
});sendTaskAssignedEvent(event: TaskAssignedEvent): Promise<void>
Sends a task assigned event.
Parameters:
event.taskId(string, required): Unique task identifierevent.taskName(string, optional): Name of the taskevent.assigneeId(string, optional): ID of the user assigned to the taskevent.assignerId(string, optional): ID of the user who assigned the taskevent.priority(number, optional): Task priority level (higher numbers indicate higher priority)event.dueDate(number, optional): Due date timestamp in milliseconds
Example:
await sdk.sendTaskAssignedEvent({
taskId: "task-123",
taskName: "Review quarterly report",
assigneeId: "user-456",
assignerId: "user-789",
priority: 5,
dueDate: Date.now() + 7 * 24 * 60 * 60 * 1000, // 7 days from now
});sendTaskCompletedEvent(event: TaskCompletedEvent): Promise<void>
Sends a task completed event.
Parameters:
event.taskId(string, required): Unique task identifierevent.completedBy(string, optional): ID of the user who completed the taskevent.duration(number, optional): Duration to complete the task in millisecondsevent.status(string, optional): Completion status (e.g., "completed", "cancelled", "failed")event.outcome(string, optional): Outcome or result of the task
Example:
await sdk.sendTaskCompletedEvent({
taskId: "task-123",
completedBy: "user-456",
duration: 3600000, // 1 hour in milliseconds
status: "completed",
outcome: "All items reviewed and approved",
});Custom Events
sendCustomEvent(event: Event): Promise<void>
Sends a custom event with full control over the event structure.
Parameters:
event(Event, required): Custom event object conforming to the Event interface
Example:
await sdk.sendCustomEvent({
id: "custom-event-123",
tenantId: "tenant-123",
sessionId: "session-123",
timestamp: Date.now(),
eventType: "custom",
properties: {
string1: "custom-value",
num1: 42,
bool1: true,
},
});Event Types
The SDK supports the following event types:
| Event Type | Constant | Description |
| ----------------------- | ------------------------- | -------------------------------------- |
| Rating | RATING | User rating events |
| Custom | CUSTOM | Custom events with flexible properties |
| Feedback Submitted | FEEDBACK_SUBMITTED | User feedback submission |
| Bug Reported | BUG_REPORTED | Bug report events |
| Survey | SURVEY | Survey started/completed events |
| Complaint Received | COMPLAINT_RECEIVED | User complaint events |
| Workflow Started | WORKFLOW_STARTED | Workflow initiation events |
| Workflow Step Completed | WORKFLOW_STEP_COMPLETED | Workflow step completion events |
| Workflow Error | WORKFLOW_ERROR | Workflow error events |
| Workflow Aborted | WORKFLOW_ABORTED | Workflow abortion events |
| Document Created | DOCUMENT_CREATED | Document creation events |
| Document Approved | DOCUMENT_APPROVED | Document approval events |
| Document Rejected | DOCUMENT_REJECTED | Document rejection events |
| Task Assigned | TASK_ASSIGNED | Task assignment events |
| Task Completed | TASK_COMPLETED | Task completion events |
Type Definitions
ClientInput
interface ClientInput {
clientType: "browser" | "server";
ip?: string;
region?: string;
city?: string;
timezone?: string;
os?: string;
osVersion?: string;
browser?: string;
browserVersion?: string;
screenResolution?: string;
utmSource?: string;
utmMedium?: string;
utmCampaign?: string;
}SessionInput
interface SessionInput {
userId?: string;
country?: string;
deviceType?: string;
referrer?: string;
}RatingEvent
interface RatingEvent {
min: number;
max: number;
source?: string;
raterId?: string;
}FeedbackEvent
interface FeedbackEvent {
text: string;
category?: string;
rating?: number;
source?: string;
}BugReportEvent
interface BugReportEvent {
description: string;
severity?: string;
stepsToReproduce?: string;
component?: string;
}SurveyEvent
interface SurveyEvent {
surveyId: string;
status: "started" | "completed";
questionCount?: number;
duration?: number;
}ComplaintEvent
interface ComplaintEvent {
text: string;
category?: string;
priority?: string;
status?: string;
}WorkflowStartedEvent
interface WorkflowStartedEvent {
workflowId: string;
workflowName?: string;
workflowType?: string;
initiatorId?: string;
}WorkflowStepCompletedEvent
interface WorkflowStepCompletedEvent {
workflowId: string;
stepId: string;
stepName?: string;
duration?: number;
status?: string;
}WorkflowErrorEvent
interface WorkflowErrorEvent {
workflowId: string;
stepId?: string;
errorType?: string;
errorMessage?: string;
errorCode?: string;
severity?: string;
}WorkflowAbortedEvent
interface WorkflowAbortedEvent {
workflowId: string;
reason?: string;
abortedBy?: string;
}DocumentCreatedEvent
interface DocumentCreatedEvent {
documentId: string;
documentType?: string;
documentName?: string;
creatorId?: string;
templateId?: string;
}DocumentApprovedEvent
interface DocumentApprovedEvent {
documentId: string;
approverId?: string;
reason?: string;
comment?: string;
}DocumentRejectedEvent
interface DocumentRejectedEvent {
documentId: string;
approverId?: string;
reason?: string;
comment?: string;
}TaskAssignedEvent
interface TaskAssignedEvent {
taskId: string;
taskName?: string;
assigneeId?: string;
assignerId?: string;
priority?: number;
dueDate?: number;
}TaskCompletedEvent
interface TaskCompletedEvent {
taskId: string;
completedBy?: string;
duration?: number;
status?: string;
outcome?: string;
}Examples
Complete Workflow Example
import { DataStudioSDK } from "data-studio-sdk";
async function trackUserJourney() {
// Initialize SDK
const sdk = new DataStudioSDK({
apiKey: "your-tenant-id@your-api-key",
});
try {
// Client is automatically created on initialization
// Start a session
await sdk.startSession({
userId: "user-123",
country: "US",
});
// Track various events
await sdk.sendRatingEvent({
rating: 1,
max: 5,
raterId: "user-123",
});
await sdk.sendFeedbackEvent({
text: "Love the new design!",
category: "ui-feedback",
rating: 5,
});
await sdk.sendSurveyEvent({
surveyId: "satisfaction-survey-2024",
status: "started",
questionCount: 5,
});
// ... user completes survey ...
await sdk.sendSurveyEvent({
surveyId: "satisfaction-survey-2024",
status: "completed",
questionCount: 5,
duration: 45000, // 45 seconds
});
// End session
await sdk.endSession();
// Close client
await sdk.closeClient();
} catch (error) {
console.error("Error tracking events:", error);
}
}Browser Integration Example
// In your React/Vue/Angular component
import { DataStudioSDK } from "data-studio-sdk";
// Initialize once (e.g., in app initialization)
const sdk = new DataStudioSDK({
apiKey: process.env.REACT_APP_DATA_STUDIO_API_KEY!,
});
// Start session when user lands on page
useEffect(() => {
sdk.startSession({
userId: currentUser?.id,
referrer: document.referrer,
});
return () => {
// End session on component unmount
sdk.endSession();
};
}, []);
// Track events on user interactions
const handleRatingSubmit = async (rating: number) => {
await sdk.sendRatingEvent({
rating: 1,
max: 5,
raterId: currentUser?.id,
});
};
const handleFeedbackSubmit = async (feedback: string) => {
await sdk.sendFeedbackEvent({
text: feedback,
category: "general",
source: "contact-form",
});
};Node.js/Server Example
import { DataStudioSDK } from "data-studio-sdk";
// Initialize with server-specific configuration
const sdk = new DataStudioSDK({
apiKey: process.env.DATA_STUDIO_API_KEY!,
});
// Create client with server info
await sdk.createClient({
clientType: "server",
ip: req.ip,
region: "us-east-1",
city: "New York",
timezone: "America/New_York",
});
// Start session
await sdk.startSession({
userId: req.user.id,
country: req.headers["cf-ipcountry"] as string,
});
// Track server-side events
await sdk.sendBugReportEvent({
description: "API endpoint returning 500 error",
severity: "critical",
component: "payment-api",
});Best Practices
Initialize Once: Create a single SDK instance and reuse it throughout your application lifecycle.
Session Management:
- Start a session when a user begins their journey
- End the session when they leave or after a period of inactivity
- Don't create multiple concurrent sessions
Error Handling: Always wrap SDK calls in try-catch blocks to handle potential errors gracefully.
Async/Await: All SDK methods are asynchronous. Always use
awaitor handle promises appropriately.Event Context: The SDK automatically adds context (sessionId, clientId, tenantId, timestamp) to all events. You don't need to provide this manually.
Browser vs Server:
- In browser environments, the SDK auto-detects device and browser information
- In server environments, provide client information manually via
createClient()
Cleanup: Always call
endSession()andcloseClient()when appropriate to ensure data is properly synced.
