ABXRLib SDK - Complete Documentation
The name "ABXR" stands for "Analytics Backbone for XR"—a flexible, open-source foundation for capturing and transmitting spatial, interaction, and performance data in XR. When combined with ArborXR Insights, ABXR transforms from a lightweight instrumentation layer into a full-scale enterprise analytics solution—unlocking powerful dashboards, LMS/BI integrations, and AI-enhanced insights.
Table of Contents
Introduction
Overview
The ABXRLib SDK is an open-source analytics and data collection library that provides developers with the tools to collect and send XR data to any service of their choice. This library enables scalable event tracking, telemetry, and session-based storage—essential for enterprise and education XR environments.
Quick Start: Most developers can integrate ABXRLib SDK and log their first event in under 15 minutes.
Why Use ABXRLib SDK?
- Open-Source & portable to any backend—no vendor lock-in
- Quick integration—track user interactions in minutes
- Secure & scalable—ready for enterprise use cases
- Pluggable with ArborXR Insights—seamless access to LMS/BI integrations, session replays, AI diagnostics, and more
Core Features
The ABXRLib SDK provides:
- Event Tracking: Monitor user behaviors, interactions, and system events.
- Spatial & Hardware Telemetry: Capture headset/controller movement and hardware metrics.
- Object & System Info: Track XR objects and environmental state.
- Storage & Session Management: Support resumable training and long-form experiences.
- Logs: Developer and system-level logs available across sessions.
Backend Services
The ABXRLib SDK is designed to work with any backend service that implements the ABXR protocol. Currently supported services include:
ArborXR Insights
When paired with ArborXR Insights, ABXR becomes a full-service platform offering:
- Seamless data pipeline from headset to dashboard
- End-to-end session tracking, analysis, and replay
- AI-driven insights for content quality, learner performance, and device usage
- One-click LMS and BI integrations for scalable deployments
Custom Implementations
Developers can implement their own backend services by following the ABXR protocol specification. This allows for complete control over data storage, processing, and visualization.
Installation
Unity Package Installation
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
- Open Unity and go to
Window > Package Manager. - Select the '+' dropdown and choose 'Add package from git URL'.
- Use the GitHub repo URL:
https://github.com/ArborXR/abxrlib-for-unity.git - Once imported, you will see
Analytics for XRin your Unity toolbar.
- Download the plugin from the GitHub repository.
- Copy the plugin folder to your project's
Pluginsdirectory. - Open your Unreal project and go to
Edit > Plugins. - Find
ABXRLib SDKand enable it. - Once imported, you will see
ABXRLib SDKconfiguration options in your Project Settings.
NPM Installation
npm install abxrlib-for-webxr
CDN Installation
<script src="https://cdn.jsdelivr.net/npm/abxrlib-for-webxr@latest/dist/abxrlib-for-webxr.js"></script>
Manual Installation
- Download the latest release from the GitHub repository.
- Include the
abxrlib-for-webxr.jsfile in your project. - Initialize the library in your application.
Configuration
Using with ArborXR Insights
To use the ABXRLib SDK with ArborXR Insights:
Get Your Credentials
- Go to the ArborXR Portal and log in.
- Grab these three values from the View Data screen of the specific app you are configuring:
- App ID
- Organization ID
- Authentication Secret
Configure Your Project
⚠️ Security Note: For production builds distributed to third parties, avoid compiling
Org IDandAuth Secretdirectly into your project. These credentials should only be compiled into builds when creating custom applications for specific individual clients. For general distribution, use ArborXR-managed devices or implement runtime credential provisioning.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
- Open
Analytics for XR > Configurationin the Unity Editor. - For Development/Testing: Paste in the App ID, Org ID, and Auth Secret. All 3 are required if you are testing from Unity itself.
- For Production Builds: Only include the App ID. Leave Org ID and Auth Secret empty for third-party distribution.
Alternative for Managed Headsets:
If you're using an ArborXR-managed device, only the App ID is required. The Org ID and Auth Secret auto-fill. On any non-managed headset, you must manually enter all three values for testing purposes only.
- Open
Edit > Project Settings > Plugins > ABXR Configurationin the Unreal Editor. - For Development/Testing: Paste in the App ID, Org ID, and Auth Secret. All 3 are required if you are testing from Unreal itself.
- For Production Builds: Only include the App ID. Leave Org ID and Auth Secret empty for third-party distribution.
Alternative for Managed Headsets:
If you're using an ArborXR-managed device, only the App ID is required. The Org ID and Auth Secret auto-fill. On any non-managed headset, you must manually enter all three values for testing purposes only.
// Initialize ABXRLib with your credentials
Abxr.init({
appId: 'your-app-id',
orgId: 'your-org-id', // Optional for managed devices
authSecret: 'your-auth-secret' // Optional for managed devices
});
Alternative for Managed Devices:
If you're using an ArborXR-managed device, only the App ID is required:
Abxr.init({
appId: 'your-app-id'
// orgId and authSecret are automatically provided
});
Using with Other Backend Services
For information on implementing your own backend service or using other compatible services, please refer to the ABXR protocol specification.
Sending Data
Events
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
//C# Event Method Signatures
public static void Abxr.Event(string name);
public static void Abxr.Event(string name, Dictionary<string, string> meta = null, bool sendTelemetry = true);
public static void Abxr.Event(string name, Vector3 position, Dictionary<string, string> meta = null);
// Example Usage - Basic Event
Abxr.Event("button_pressed");
// Example Usage - Event with Metadata
Abxr.Event("item_collected", new Abxr.Dict {
{"item_type", "coin"},
{"item_value", "100"}
});
// Example Usage - Event with Metadata and Location
Abxr.Event("player_teleported",
new Abxr.Dict {{"destination", "spawn_point"}},
new Vector3(1.5f, 0.0f, -3.2f)
);
Platform-Specific Notes:
- Use
Abxr.Dictto avoid requiring using statements location_dataparameter is a Vector3
//C++ Event Method Signatures
public static void Event(const FString& Name);
public static void Event(const FString& Name, TMap<FString, FString>& Meta);
// Example Usage - Basic Event
UAbxr::Event(TEXT("button_pressed"));
// Example Usage - Event with Metadata
TMap<FString, FString> Meta;
Meta.Add(TEXT("item_type"), TEXT("coin"));
Meta.Add(TEXT("item_value"), TEXT("100"));
UAbxr::Event(TEXT("item_collected"), Meta);
Platform-Specific Notes:
- Use
TEXT()macro for string literals - Metadata uses
TMap<FString, FString>
// JavaScript Event Method Signatures
static async Event(name: string, meta?: any): Promise<number>
static async Event(name: string, position: Vector3, meta?: any): Promise<number>
// Example Usage - Basic Event
Abxr.Event('button_pressed');
// Example Usage - Event with Metadata
Abxr.Event('item_collected', {
item_type: 'coin',
item_value: '100'
});
// Example Usage - Event with Metadata and Location
Abxr.Event('player_teleported',
{ destination: 'spawn_point' },
{ x: 1.5, y: 0.0, z: -3.2 }
);
Platform-Specific Notes:
- Use single quotes for strings
positionparameter is a Vector3 object- Methods return Promise<number>
Logs a named event with optional metadata and spatial context. Timestamps and origin (user or system) are automatically appended.
Parameters:
name: The name of the event. Use snake_case for better analytics processing.meta: Optional. Additional key-value pairs describing the event.position/location_data: Optional. The (x, y, z) coordinates of the event in 3D space.
Analytics Event Wrappers (Essential for All Developers)
These analytics event functions are essential for ALL developers They provide standardized tracking for key user interactions and learning outcomes that are crucial for understanding user behavior, measuring engagement, and optimizing XR experiences and power the analytics dashboards and reporting features. They also essential for integrations with Learning Management System (LMS) platforms.
EventAssessmentStart and EventAssessmentComplete are REQUIRED for all ArborXR Insights usage
Assessments, Objectives & Interactions
These three event types work together to provide comprehensive tracking of user progress:
-
Assessment: Tracks overall performance across an entire experience, course, or curriculum. Think of it as the final score or outcome for a complete learning module. When an Assessment completes, it automatically records and closes out the session in supported LMS platforms.
-
Objective: Tracks specific learning goals or sub-tasks within an assessment. These represent individual skills, concepts, or milestones that contribute to the overall assessment score.
-
Interaction: Tracks individual user responses or actions within an objective or assessment. These capture specific user inputs, choices, or behaviors that demonstrate engagement and learning progress.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// Status enumeration for all analytics events
public enum EventStatus { Pass, Fail, Complete, Incomplete, Browsed, NotAttempted }
public enum InteractionType { Null, Bool, Select, Text, Rating, Number, Matching, Performance, Sequencing }
public enum InteractionResult { Correct, Incorrect, Neutral } // defaults to Neutral
//C# Method Signatures
public static void Abxr.EventAssessmentStart(string assessmentName, Dictionary<string, string> meta = null);
public static void Abxr.EventAssessmentComplete(string assessmentName, int score, EventStatus status, Dictionary<string, string> meta = null);
public static void Abxr.EventExperienceStart(string assessmentName, Dictionary<string, string> meta = null);
public static void Abxr.EventExperienceComplete(string assessmentName, Dictionary<string, string> meta = null);
public static void Abxr.EventObjectiveStart(string objectiveName, Dictionary<string, string> meta = null);
public static void Abxr.EventObjectiveComplete(string objectiveName, int score, EventStatus status, Dictionary<string, string> meta = null);
public static void Abxr.EventInteractionStart(string interactionName, Dictionary<string, string> meta = null);
public static void Abxr.EventInteractionComplete(string interactionName, InteractionType type, InteractionResult result, string response, Dictionary<string, string> meta = null);
// Assessment tracking (overall course/curriculum performance)
Abxr.EventAssessmentStart("final_exam");
Abxr.EventAssessmentComplete("final_exam", 92, EventStatus.Pass);
// or if score is not relevant
Abxr.EventExperienceStart("exploration_1");
Abxr.EventExperienceComplete("exploration_1");
// Objective tracking (specific learning goals)
Abxr.EventObjectiveStart("open_valve");
Abxr.EventObjectiveComplete("open_valve", 100, EventStatus.Complete);
// Interaction tracking (individual user responses)
Abxr.EventInteractionStart("select_option_a");
Abxr.EventInteractionComplete("select_option_a", InteractionType.Select, "true");
// Status enumeration for all analytics events
public enum EEventStatus { Pass, Fail, Complete, Incomplete, Browsed }
public enum EInteractionType { Null, Bool, Select, Text, Rating, Number, Matching, Performance, Sequencing }
//C++ Method Signatures
public static void UAbxr::EventAssessmentStart(const FString& AssessmentName);
public static void UAbxr::EventAssessmentStart(const FString& AssessmentName, TMap<FString, FString>& Meta);
public static void UAbxr::EventAssessmentComplete(const FString& AssessmentName, int32 Score, EEventStatus Status);
public static void UAbxr::EventAssessmentComplete(const FString& AssessmentName, int32 Score, EEventStatus Status, TMap<FString, FString>& Meta);
public static void UAbxr::EventExperienceStart(const FString& ExperienceName);
public static void UAbxr::EventExperienceStart(const FString& ExperienceName, TMap<FString, FString>& Meta);
public static void UAbxr::EventExperienceComplete(const FString& ExperienceName);
public static void UAbxr::EventExperienceComplete(const FString& ExperienceName, TMap<FString, FString>& Meta);
public static void UAbxr::EventObjectiveStart(const FString& ObjectiveName);
public static void UAbxr::EventObjectiveStart(const FString& ObjectiveName, TMap<FString, FString>& Meta);
public static void UAbxr::EventObjectiveComplete(const FString& ObjectiveName, int32 Score, EEventStatus Status);
public static void UAbxr::EventObjectiveComplete(const FString& ObjectiveName, int32 Score, EEventStatus Status, TMap<FString, FString>& Meta);
public static void UAbxr::EventInteractionStart(const FString& InteractionName);
public static void UAbxr::EventInteractionStart(const FString& InteractionName, TMap<FString, FString>& Meta);
public static void UAbxr::EventInteractionComplete(const FString& InteractionName, EInteractionType Type, const FString& Result);
public static void UAbxr::EventInteractionComplete(const FString& InteractionName, EInteractionType Type, const FString& Result, TMap<FString, FString>& Meta);
// Assessment tracking (overall course/curriculum performance)
UAbxr::EventAssessmentStart(TEXT("final_exam"));
UAbxr::EventAssessmentComplete(TEXT("final_exam"), 92, EEventStatus::Pass);
// or if score is not relevant
UAbxr::EventExperienceStart(TEXT("exploration_1"));
UAbxr::EventExperienceComplete(TEXT("exploration_1"));
// Objective tracking (specific learning goals)
UAbxr::EventObjectiveStart(TEXT("open_valve"));
UAbxr::EventObjectiveComplete(TEXT("open_valve"), 100, EEventStatus::Complete);
// Interaction tracking (individual user responses)
UAbxr::EventInteractionStart(TEXT("select_option_a"));
UAbxr::EventInteractionComplete(TEXT("select_option_a"), EInteractionType::Select, TEXT("true"));
// Status enumeration for all analytics events
Abxr.EventStatus.Pass, Abxr.EventStatus.Fail, Abxr.EventStatus.Complete, Abxr.EventStatus.Incomplete, Abxr.EventStatus.Browsed, Abxr.EventStatus.NotAttempted
Abxr.InteractionType.Null, Abxr.InteractionType.Bool, Abxr.InteractionType.Select, Abxr.InteractionType.Text, Abxr.InteractionType.Rating, Abxr.InteractionType.Number
Abxr.InteractionResult.Correct, Abxr.InteractionResult.Incorrect, Abxr.InteractionResult.Neutral // defaults to Neutral
// JavaScript Method Signatures
static async EventAssessmentStart(assessmentName: string, meta?: any): Promise<number>
static async EventAssessmentComplete(assessmentName: string, score: number | string, eventStatus: EventStatus, meta?: any): Promise<number>
static async EventExperienceStart(experienceName: string, meta?: any): Promise<number>
static async EventExperienceComplete(experienceName: string, meta?: any): Promise<number>
static async EventObjectiveStart(objectiveName: string, meta?: any): Promise<number>
static async EventObjectiveComplete(objectiveName: string, score: number | string, eventStatus: EventStatus, meta?: any): Promise<number>
static async EventInteractionStart(interactionName: string, meta?: any): Promise<number>
static async EventInteractionComplete(interactionName: string, interactionType: InteractionType, result: InteractionResult = "neutral", response: string = "", meta?: any): Promise<number>
// Assessment tracking (overall course/curriculum performance)
Abxr.EventAssessmentStart('final_exam');
Abxr.EventAssessmentComplete('final_exam', 92, Abxr.EventStatus.Pass);
// or if score is not relevant
Abxr.EventExperienceStart('exploration_1');
Abxr.EventExperienceComplete('exploration_1');
// Objective tracking (specific learning goals)
Abxr.EventObjectiveStart('open_valve');
Abxr.EventObjectiveComplete('open_valve', 100, Abxr.EventStatus.Complete);
// Interaction tracking (individual user responses)
Abxr.EventInteractionStart('select_option_a');
Abxr.EventInteractionComplete('select_option_a', Abxr.InteractionType.Select, Abxr.InteractionResult.Correct, 'true');
Additional Event Wrappers
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
//C# Method Signatures
public static void Abxr.EventLevelStart(string levelName, Dictionary<string, string> meta = null);
public static void Abxr.EventLevelComplete(string levelName, int score, Dictionary<string, string> meta = null);
public static void Abxr.EventCritical(string eventName, Dictionary<string, string> meta = null);
// Level tracking
Abxr.EventLevelStart("level_1");
Abxr.EventLevelComplete("level_1", 85);
// Critical event flagging (for safety training, high-risk errors, etc.)
Abxr.EventCritical("safety_violation");
//C++ Method Signatures
public static void UAbxr::EventLevelStart(const FString& LevelName);
public static void UAbxr::EventLevelStart(const FString& LevelName, TMap<FString, FString>& Meta);
public static void UAbxr::EventLevelComplete(const FString& LevelName, int32 Score);
public static void UAbxr::EventLevelComplete(const FString& LevelName, int32 Score, TMap<FString, FString>& Meta);
public static void UAbxr::EventCritical(const FString& EventName);
public static void UAbxr::EventCritical(const FString& EventName, TMap<FString, FString>& Meta);
// Level tracking
UAbxr::EventLevelStart(TEXT("level_1"));
UAbxr::EventLevelComplete(TEXT("level_1"), 85);
// Critical event flagging (for safety training, high-risk errors, etc.)
UAbxr::EventCritical(TEXT("safety_violation"));
// JavaScript Method Signatures
static async EventLevelStart(levelName: string, meta?: any): Promise<number>
static async EventLevelComplete(levelName: string, score: number | string, meta?: any): Promise<number>
static async EventCritical(eventName: string, meta?: any): Promise<number>
// Level tracking
Abxr.EventLevelStart('level_1');
Abxr.EventLevelComplete('level_1', 85);
// Critical event flagging (for safety training, high-risk errors, etc.)
Abxr.EventCritical('safety_violation');
Parameters for all Event Wrapper Functions:
levelName/assessmentName/objectiveName/interactionName(string): The identifier for the assessment, objective, interaction, or level.score(int): The numerical score achieved. While typically between 1-100, any integer is valid. In metadata, you can also set a minScore and maxScore to define the range of scores for this objective.result(Interactions): The result for the interaction is based on theInteractionType.result_details(string): Optional. Additional details about the result. For interactions, this can be a single character or a string. For example: "a", "b", "c" or "correct", "incorrect".type(InteractionType): Optional. The type of interaction for this event.meta(Dictionary<string, string>orAbxr.Dict): Optional. Additional key-value pairs describing the event. UseAbxr.Dictto avoid requiring using statements.
Note: All complete events automatically calculate duration if a corresponding start event was logged.
Timed Events
The ABXRLib SDK includes a built-in timing system that allows you to measure the duration of any event. This is useful for tracking how long users spend on specific activities.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
//C# Timed Event Method Signature
public static void Abxr.StartTimedEvent(string eventName)
// Example Usage
Abxr.StartTimedEvent("Table puzzle");
// ... user performs puzzle activity for 20 seconds ...
Abxr.Event("Table puzzle"); // Duration automatically included: 20 seconds
// Works with all event methods
Abxr.StartTimedEvent("Assessment");
// ... later ...
Abxr.EventAssessmentComplete("Assessment", 95, EventStatus.Pass); // Duration included
// or if score is not relevant
Abxr.EventExperienceComplete("Assessment"); // Duration included
// Also works with Mixpanel compatibility methods
Abxr.StartTimedEvent("User Session");
// ... later ...
Abxr.Track("User Session"); // Duration automatically included
// C++ Timed Event Method Signature
public static void UAbxr::StartTimedEvent(const FString& EventName);
// Example Usage
UAbxr::StartTimedEvent(TEXT("Table puzzle"));
// ... user performs puzzle activity for 20 seconds ...
UAbxr::Event(TEXT("Table puzzle")); // Duration automatically included: 20 seconds
// Works with all event methods
UAbxr::StartTimedEvent(TEXT("Assessment"));
// ... later ...
UAbxr::EventAssessmentComplete(TEXT("Assessment"), 95, EEventStatus::Pass); // Duration included
// or if score is not relevant
UAbxr::EventExperienceComplete(TEXT("Assessment")); // Duration included
// Also works with Mixpanel compatibility methods
UAbxr::StartTimedEvent(TEXT("User Session"));
// ... later ...
UAbxr::Track(TEXT("User Session")); // Duration automatically included
// JavaScript Timed Event Method Signature
static StartTimedEvent(eventName: string): void
// Example Usage
Abxr.StartTimedEvent("Table puzzle");
// ... user performs puzzle activity for 20 seconds ...
Abxr.Event("Table puzzle"); // Duration automatically included: 20 seconds
// Works with all event methods
Abxr.StartTimedEvent("Assessment");
// ... later ...
Abxr.EventAssessmentComplete("Assessment", 95, Abxr.EventStatus.Pass); // Duration included
// or if score is not relevant
Abxr.EventExperienceComplete("Assessment"); // Duration included
// Also works with Mixpanel compatibility methods
Abxr.StartTimedEvent("User Session");
// ... later ...
Abxr.Track("User Session"); // Duration automatically included
Parameters:
eventName: The name of the event to start timing. Must match the event name used later.
Note: The timer automatically adds a duration field (in seconds) to any subsequent event with the same name. The timer is automatically removed after the first matching event.
Quick Start Guide
Once installed and configuration is complete, you can start tracking events immediately:
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// Add at the start your training (or training module)
Abxr.EventAssessmentStart("safety_training1");
// Add at the end your training (or training module)
Abxr.EventAssessmentComplete("safety_training1", 92, EventStatus.Pass);
// or
Abxr.EventAssessmentComplete("safety_training1", 28, EventStatus.Fail);
// or if a score is not relevant
// Add at the start your training (or training module)
Abxr.EventExperienceStart("safety_training1");
// Add at the end your training (or training module)
Abxr.EventExperienceComplete("safety_training1");
In many cases you may want to track sub-tasks within the content:
// To track objectives
Abxr.EventObjectiveStart("open_valve");
Abxr.EventObjectiveComplete("open_valve", 100, EventStatus.Complete);
// Interaction tracking (individual user responses)
Abxr.EventInteractionStart("select_option_a");
Abxr.EventInteractionComplete("select_option_a", InteractionType.Select, "true");
// Add at the start your training (or training module)
UAbxr::EventAssessmentStart(TEXT("safety_training1"));
// Add at the end your training (or training module)
UAbxr::EventAssessmentComplete(TEXT("safety_training1"), 92, EEventStatus::Pass);
// or
UAbxr::EventAssessmentComplete(TEXT("safety_training1"), 28, EEventStatus::Fail);
// or if a score is not relevant
// Add at the start your training (or training module)
UAbxr::EventExperienceStart(TEXT("safety_training1"));
// Add at the end your training (or training module)
UAbxr::EventExperienceComplete(TEXT("safety_training1"));
In many cases you may want to track sub-tasks within the content:
// To track objectives
UAbxr::EventObjectiveStart(TEXT("open_valve"));
UAbxr::EventObjectiveComplete(TEXT("open_valve"), 100, EEventStatus::Complete);
// Interaction tracking (individual user responses)
UAbxr::EventInteractionStart(TEXT("select_option_a"));
UAbxr::EventInteractionComplete(TEXT("select_option_a"), EInteractionType::Select, TEXT("true"));
// Add at the start your training (or training module)
Abxr.EventAssessmentStart('safety_training1');
// Add at the end your training (or training module)
Abxr.EventAssessmentComplete('safety_training1', 92, Abxr.EventStatus.Pass);
// or
Abxr.EventAssessmentComplete('safety_training1', 28, Abxr.EventStatus.Fail);
// or if a score is not relevant
// Add at the start your training (or training module)
Abxr.EventExperienceStart('safety_training1');
// Add at the end your training (or training module)
Abxr.EventExperienceComplete('safety_training1');
In many cases you may want to track sub-tasks within the content:
// To track objectives
Abxr.EventObjectiveStart('open_valve');
Abxr.EventObjectiveComplete('open_valve', 100, Abxr.EventStatus.Complete);
// Interaction tracking (individual user responses)
Abxr.EventInteractionStart('select_option_a');
Abxr.EventInteractionComplete('select_option_a', Abxr.InteractionType.Select, 'true');
Super Meta Data
Global metadata automatically included in all events, logs, and telemetry data.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
//C# Method Signatures
public static void Abxr.Register(string key, string value);
public static void Abxr.RegisterOnce(string key, string value);
// Set persistent "super metadata" (included in all events, logs, and telemetry)
Abxr.Register("user_type", "premium");
Abxr.Register("app_version", "1.2.3");
// Set only if not already set
Abxr.RegisterOnce("user_tier", "free");
// Management
Abxr.Unregister("device_type"); // Remove specific super metadata
Abxr.Reset(); // Clear all super metadata
//C++ Method Signatures
public static void UAbxr::Register(const FString& Key, const FString& Value);
public static void UAbxr::RegisterOnce(const FString& Key, const FString& Value);
// Set persistent properties (included in all events)
UAbxr::Register(TEXT("user_type"), TEXT("premium"));
UAbxr::Register(TEXT("app_version"), TEXT("1.2.3"));
// Set only if not already set
UAbxr::RegisterOnce(TEXT("user_tier"), TEXT("free"));
// Management
UAbxr::Unregister(TEXT("device_type")); // Remove specific property
UAbxr::Reset(); // Clear all super properties
// JavaScript Method Signatures
static Register(key: string, value: string): void
static RegisterOnce(key: string, value: string): void
// Set persistent "super metadata" (included in all events, logs, and telemetry)
Abxr.Register("user_type", "premium");
Abxr.Register("app_version", "1.2.3");
// Set only if not already set
Abxr.RegisterOnce("user_tier", "free");
// Management
Abxr.Unregister("device_type"); // Remove specific super metadata
Abxr.Reset(); // Clear all super metadata
Perfect for user attributes, app state, and device information that should be included with every event, log entry, and telemetry data point.
Logging
The Log Methods provide straightforward logging functionality, similar to syslogs. These functions are available to developers by default, even across enterprise users, allowing for consistent and accessible logging across different deployment scenarios.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
//C# Method Signatures
public static void Abxr.Log(string message, LogLevel level = LogLevel.Info, Dictionary<string, string> meta = null)
// Example usage
Abxr.Log("Module started"); // Defaults to LogLevel.Info
Abxr.Log("Module started", LogLevel.Info);
Abxr.Log("Debug information", LogLevel.Debug);
Use standard or severity-specific logging:
//C# Method Signatures
public static void Abxr.LogDebug(string text, Dictionary<string, string> meta = null)
public static void Abxr.LogInfo(string text, Dictionary<string, string> meta = null)
public static void Abxr.LogWarn(string text, Dictionary<string, string> meta = null)
public static void Abxr.LogError(string text, Dictionary<string, string> meta = null)
public static void Abxr.LogCritical(string text, Dictionary<string, string> meta = null)
// Example usage
Abxr.LogError("Critical error in assessment phase");
// With metadata
Abxr.LogDebug("User interaction", new Abxr.Dict {
{"action", "button_click"},
{"screen", "main_menu"}
});
//C++ Event Method Signatures
public static void UAbxr::Log(const FString& Message, ELogLevel Level = ELogLevel::Info)
// Example usage
UAbxr::Log(TEXT("Module started")); // Defaults to ELogLevel::Info
UAbxr::Log(TEXT("Module started"), ELogLevel::Info);
UAbxr::Log(TEXT("Debug information"), ELogLevel::Debug);
UAbxr::Log(TEXT("Error occurred"), ELogLevel::Error);
Use standard or severity-specific logging:
//C++ Method Signatures
public static void LogDebug(const FString& Message)
public static void LogInfo(const FString& Message)
public static void LogWarn(const FString& Message)
public static void LogError(const FString& Message)
public static void LogCritical(const FString& Message)
// Example usage
UAbxr::LogError(TEXT("Critical error in assessment phase"));
// JavaScript Method Signatures
static async Log(message: string, level: LogLevel = LogLevel.Info, meta?: any): Promise<number>
// Example usage
Abxr.Log("Module started"); // Defaults to LogLevel.Info
Abxr.Log("Module started", Abxr.LogLevel.Info);
Abxr.Log("Debug information", Abxr.LogLevel.Debug);
Use standard or severity-specific logging:
// JavaScript Method Signatures
static async LogDebug(message: string, meta?: any): Promise<number>
static async LogInfo(message: string, meta?: any): Promise<number>
static async LogWarn(message: string, meta?: any): Promise<number>
static async LogError(message: string, meta?: any): Promise<number>
static async LogCritical(message: string, meta?: any): Promise<number>
// Example usage
Abxr.LogError("Critical error in assessment phase");
// With metadata
Abxr.LogDebug("User interaction", {
action: "button_click",
screen: "main_menu"
});
Storage
The Storage API enables developers to store and retrieve learner/player progress, facilitating the creation of long-form training content. When users log in using ArborXR's facility or the developer's in-app solution, these methods allow users to continue their progress on different headsets, ensuring a seamless learning experience across multiple sessions or devices.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
//C# Method Signatures
public static void Abxr.StorageSetEntry(string name, Dictionary<string, string> entry, StorageScope scope, StoragePolicy policy = StoragePolicy.keepLatest);
public static void Abxr.StorageSetDefaultEntry(Dictionary<string, string> entry, StorageScope scope, StoragePolicy policy = StoragePolicy.keepLatest);
public static IEnumerator Abxr.StorageGetEntry(string name, StorageScope scope, Action<List<Dictionary<string, string>>> callback);
public static IEnumerator Abxr.StorageGetDefaultEntry(StorageScope scope, Action<List<Dictionary<string, string>>> callback);
public static void Abxr.StorageRemoveEntry(string name, StorageScope scope);
// Save progress data
Abxr.StorageSetEntry("state", new Abxr.Dict{{"progress", "75%"}}, StorageScope.user);
Abxr.StorageSetDefaultEntry(new Abxr.Dict{{"progress", "75%"}}, StorageScope.user);
// Retrieve progress data (requires coroutine)
StartCoroutine(Abxr.StorageGetEntry("state", StorageScope.user, result => {
Debug.Log("Retrieved data: " + result);
}));
StartCoroutine(Abxr.StorageGetDefaultEntry(StorageScope.user, result => {
Debug.Log("Retrieved default data: " + result);
}));
// Remove storage entries
Abxr.StorageRemoveEntry("state", StorageScope.user);
Abxr.StorageRemoveDefaultEntry(StorageScope.user);
Abxr.StorageRemoveMultipleEntries(StorageScope.user); // Clear all entries (use with caution)
Parameters:
name(string): The identifier for this storage entry.entry(Dictionary<string, string>orAbxr.Dict): The key-value pairs to store. UseAbxr.Dictto avoid requiring using statements.scope(StorageScope): Store/retrieve from 'device' or 'user' storage.policy(StoragePolicy): How data should be stored - 'keepLatest' or 'appendHistory' (defaults to 'keepLatest').callback(Action): Callback function for retrieval operations.
//C++ Method Signatures
public static void UAbxr::StorageSetEntry(const FString& Name, TMap<FString, FString>& Entry, EStorageScope Scope, EStoragePolicy Policy = EStoragePolicy::KeepLatest);
public static void UAbxr::StorageSetDefaultEntry(TMap<FString, FString>& Entry, EStorageScope Scope, EStoragePolicy Policy = EStoragePolicy::KeepLatest);
public static void UAbxr::StorageGetEntry(const FString& Name, EStorageScope Scope, /* callback */);
public static void UAbxr::StorageGetDefaultEntry(EStorageScope Scope, /* callback */);
public static void UAbxr::StorageRemoveEntry(const FString& Name, EStorageScope Scope);
// Save progress data
UAbxr::StorageSetEntry(TEXT("state"), TMap<FString, FString>{{TEXT("progress"), TEXT("75%")}}, EStorageScope::User);
UAbxr::StorageSetDefaultEntry(TMap<FString, FString>{{TEXT("progress"), TEXT("75%")}}, EStorageScope::User);
// Retrieve progress data (requires coroutine)
// Note: Implement coroutine-based retrieval in Unreal as needed
UAbxr::StorageGetEntry(TEXT("state"), EStorageScope::User, /* callback */);
UAbxr::StorageGetDefaultEntry(EStorageScope::User, /* callback */);
// Remove storage entries
UAbxr::StorageRemoveEntry(TEXT("state"), EStorageScope::User);
UAbxr::StorageRemoveDefaultEntry(EStorageScope::User);
UAbxr::StorageRemoveMultipleEntries(EStorageScope::User); // Clear all entries (use with caution)
Parameters:
Name(FString): The identifier for this storage entry.Entry(TMap<FString, FString>): The key-value pairs to store.Scope(EStorageScope): Store/retrieve from 'device' or 'user' storage.Policy(EStoragePolicy): How data should be stored - 'KeepLatest' or 'AppendHistory' (defaults to 'KeepLatest').
// JavaScript Method Signatures
static async StorageSetEntry(name: string, entry: {[key: string]: string}, scope: Abxr.StorageScope, policy: Abxr.StoragePolicy = Abxr.StoragePolicy.keepLatest): Promise<number>
static async StorageSetDefaultEntry(entry: {[key: string]: string}, scope: Abxr.StorageScope, policy: Abxr.StoragePolicy = Abxr.StoragePolicy.keepLatest): Promise<number>
static async StorageGetEntry(name: string, scope: Abxr.StorageScope): Promise<{[key: string]: string}[]>
static async StorageGetDefaultEntry(scope: Abxr.StorageScope): Promise<{[key: string]: string}[]>
static async StorageRemoveEntry(name: string = "state", scope: Abxr.StorageScope = Abxr.StorageScope.user): Promise<number>
static async StorageRemoveDefaultEntry(scope: Abxr.StorageScope = Abxr.StorageScope.user): Promise<number>
static async StorageRemoveMultipleEntries(scope: Abxr.StorageScope = Abxr.StorageScope.user): Promise<number>
// Save progress data
Abxr.StorageSetEntry("state", {"progress": "75%"}, Abxr.StorageScope.user);
Abxr.StorageSetDefaultEntry({"progress": "75%"}, Abxr.StorageScope.user);
// Using StoragePolicy enum explicitly
Abxr.StorageSetEntry("state", {"progress": "75%"}, Abxr.StorageScope.user, Abxr.StoragePolicy.keepLatest);
Abxr.StorageSetEntry("history", {"action": "completed_level_1"}, Abxr.StorageScope.user, Abxr.StoragePolicy.appendHistory);
// Retrieve progress data
const result = await Abxr.StorageGetEntry("state", Abxr.StorageScope.user);
console.log("Retrieved data:", result);
const defaultResult = await Abxr.StorageGetDefaultEntry(Abxr.StorageScope.user);
console.log("Retrieved default data:", defaultResult);
// Remove storage entries
Abxr.StorageRemoveEntry("state", Abxr.StorageScope.user);
Abxr.StorageRemoveDefaultEntry(Abxr.StorageScope.user);
Abxr.StorageRemoveMultipleEntries(Abxr.StorageScope.user); // Clear all entries (use with caution)
Parameters:
name(string): The identifier for this storage entry.entry(object): The key-value pairs to store.scope(Abxr.StorageScope): Store/retrieve from 'device' or 'user' storage.policy(Abxr.StoragePolicy): How data should be stored - 'keepLatest' or 'appendHistory' (defaults to 'keepLatest').
Telemetry
The Telemetry Methods provide comprehensive tracking of the XR environment. By default, they capture headset and controller movements, but can be extended to track any custom objects in the virtual space. These functions also allow collection of system-level data such as frame rates or device temperatures. This versatile tracking enables developers to gain deep insights into user interactions and application performance, facilitating optimization and enhancing the overall XR experience.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
//C# Method Signatures
public static void Abxr.Telemetry(string name, Dictionary<string, string> meta);
// Manual telemetry activation (when auto-telemetry is disabled)
Abxr.TrackAutoTelemetry();
// Custom telemetry logging
Abxr.Telemetry("headset_position", new Abxr.Dict {
{"x", "1.23"}, {"y", "4.56"}, {"z", "7.89"}
});
Parameters:
name(string): The type of telemetry data (e.g., "headset_position", "frame_rate", "battery_level").meta(Dictionary<string, string>orAbxr.Dict): Key-value pairs of telemetry measurements. UseAbxr.Dictto avoid requiring using statements.
//C++ Method Signatures
public static void UAbxr::TelemetryEntry(const FString& Name, TMap<FString, FString>& Meta);
// Example usage
UAbxr::TelemetryEntry(TEXT("headset_position"), TMap<FString, FString> { {TEXT("x"), TEXT("1.23")}, {TEXT("y"), TEXT("4.56")}, {TEXT("z"), TEXT("7.89")} });
Parameters:
Name(FString): The type of telemetry data (e.g., "headset_position", "frame_rate", "battery_level").Meta(TMap<FString, FString>): Key-value pairs of telemetry measurements.
// JavaScript Method Signatures
static async Telemetry(name: string, data: any): Promise<number>
// Custom telemetry logging (fire-and-forget)
Abxr.Telemetry("headset_position", {
"x": "1.23", "y": "4.56", "z": "7.89"
});
Parameters:
name(string): The type of telemetry data (e.g., "headset_position", "frame_rate", "battery_level").data(object): Key-value pairs of telemetry measurements.
AI Integration
The AI Integration methods provide access to AI services for enhanced user interactions and experiences within XR environments.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// Access GPT services for AI-powered interactions (requires coroutine)
StartCoroutine(Abxr.AIProxy("How can I help you today?", "gpt-4", result => {
Debug.Log("AI Response: " + result);
}));
// With previous messages for context
var pastMessages = new List<string> {"Hello", "Hi there! How can I help?"};
StartCoroutine(Abxr.AIProxy("What's the weather like?", pastMessages, "gpt-4", result => {
Debug.Log("AI Response: " + result);
}));
Parameters:
prompt(string): The input prompt for the AI.llmProvider(string): The LLM provider identifier.pastMessages(List<string>): Optional. Previous conversation history for context.callback(Action<string>): Callback function that receives the AI response.
Note: AIProxy calls are processed immediately and bypass the cache system.
Note: AI Integration is currently only available in Unity and WebXR. Unreal Engine support is planned for future releases.
// Non-blocking approach - process response when ready
Abxr.AIProxy("How can I help you today?", "gpt-4").then(response => {
if (response) {
console.log("AI Response:", response);
// Process the AI response without blocking
} else {
console.log("AI request failed");
}
});
// Blocking approach - wait for response
const response = await Abxr.AIProxy("What's the weather like?", "gpt-4");
if (response) {
console.log("Weather:", response);
}
// With conversation history for context
const pastMessages = ["Hello", "Hi there! How can I help?"];
const response = await Abxr.AIProxy("What's the weather like?", pastMessages, "gpt-4");
Parameters:
prompt(string): The input prompt for the AI.llmProvider(string): The LLM provider identifier.pastMessages(array): Optional. Previous conversation history for context.
Exit Polls
Deliver questionnaires to users to gather feedback.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// Poll type enumeration
public enum PollType { Thumbs, Rating, MultipleChoice }
//C# Method Signatures
public static void Abxr.PollUser(string prompt, ExitPollHandler.PollType pollType, List<string> responses = null, Action<string> callback = null);
// Poll types: Thumbs, Rating (1-5), MultipleChoice (2-8 options)
Abxr.PollUser("How would you rate this training experience?", ExitPollHandler.PollType.Rating);
Note: Exit Polls are currently only available in Unity and WebXR. Unreal Engine support is planned for future releases.
// Poll type enumeration
Abxr.PollType.Thumbs, Abxr.PollType.Rating, Abxr.PollType.MultipleChoice
// JavaScript Method Signatures
Abxr.PollUser(prompt, pollType, responses?, callback?)
Abxr.HideExitPoll()
// Poll types: Thumbs, Rating (1-5), MultipleChoice (2-8 options)
Abxr.PollUser("How would you rate this training experience?", Abxr.PollType.Rating);
// Multiple choice poll with custom responses
Abxr.PollUser("What was your favorite part?", Abxr.PollType.MultipleChoice,
["Safety Training", "Equipment Check", "Emergency Procedures"]);
Metadata Formats
The ABXRLib SDK supports multiple flexible metadata formats. All formats are automatically converted to key-value pairs:
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// 1. Abxr.Dict (Recommended)
Abxr.Event("user_action", new Abxr.Dict
{
["action"] = "click",
["userId"] = "12345"
});
// 2. Abxr.Dict with fluent API
Abxr.Event("purchase_complete", new Abxr.Dict()
.With("amount", "29.99")
.With("currency", "USD")
.With("plan", "Premium"));
// 3. Mixpanel-style Dictionary (auto-converts objects)
Abxr.Track("assessment_complete", new Dictionary<string, object>
{
["score"] = 95, // → "95"
["completed"] = true, // → "true"
["timestamp"] = DateTime.UtcNow // → ISO string
});
// 4. Abxr.Value class (Mixpanel compatibility)
var props = new Abxr.Value();
props["plan"] = "Premium";
props["amount"] = 29.99;
Abxr.Track("purchase_completed", props);
// 5. No metadata
Abxr.Event("app_started");
// 6. With Unity Vector3 position data
Abxr.Event("player_teleported", transform.position,
new Abxr.Dict { ["destination"] = "spawn_point" });
JSON Arrays in Metadata
Use pre-serialized JSON strings:
var meta = new Abxr.Dict
{
["items"] = "[\"sword\", \"shield\", \"potion\"]",
["scores"] = "[95, 87, 92, 88]"
};
Avoid raw arrays/lists:
// Don't do this - becomes "System.String[]"
["items"] = new string[] {"sword", "shield", "potion"}
Key Takeaways:
- Use
Abxr.Dictfor simplicity - No using statements required, clean syntax - Always serialize arrays to JSON strings before passing to ABXRLib SDK methods
- All event and log methods support these flexible metadata formats
// 1. TMap<FString, FString> (Recommended)
TMap<FString, FString> Meta;
Meta.Add(TEXT("action"), TEXT("click"));
Meta.Add(TEXT("userId"), TEXT("12345"));
UAbxr::Event(TEXT("user_action"), Meta);
// 2. No metadata
UAbxr::Event(TEXT("app_started"));
// 3. With Unreal Vector3 position data
FVector Position(1.5f, 0.0f, -3.2f);
UAbxr::Event(TEXT("player_teleported"), Position, Meta);
Key Takeaways:
- Use
TMap<FString, FString>for metadata - Use
TEXT()macro for string literals - All event and log methods support these flexible metadata formats
// 1. Native JavaScript Objects (most efficient)
Abxr.Event("user_action", {
"action": "click",
"userId": "12345"
});
// 2. JSON Strings (auto-converts objects)
Abxr.Track("assessment_complete", '{"score": 95, "completed": true}');
// 3. No metadata
Abxr.Event("app_started");
// 4. With WebXR Vector3 position data
Abxr.Event("player_teleported", { x: 1.5, y: 0.0, z: -3.2 }, {
"destination": "spawn_point"
});
Key Takeaway: All event and log methods support these flexible metadata formats
Advanced Features
Module Targets
The Module Target feature enables developers to create single applications with multiple modules, where users can be assigned to specific module(s) and the application can automatically direct users to their assigned module within the application. When combined with Insights LMS integration, each module can be its own assignment, and individual grades and results are tracked for that specific assignment.
Note: Module Targets are supported in Unity and WebXR. Unreal Engine support is planned for future releases.
Setting Up Module Tracking
When building multi-module applications, you have two approaches depending on your architecture:
Option 1: Using Common Module Wrappers (Recommended for Large Apps)
If your app has common start/stop wrappers around modules (e.g., a base class or shared initialization code), add EventAssessmentStart and EventAssessmentComplete in those wrappers. EventExperienceStart and EventExperienceComplete can be used in the case where a score is not relevant:
// In your common module wrapper/initialization code
void StartModule(string moduleName)
{
// EventAssessmentStart automatically sets the module metadata
// when NOT in an auth-provided module sequence
Abxr.EventAssessmentStart(moduleName);
// Your module initialization code here
LoadModuleContent(moduleName);
}
void CompleteModule(string moduleName, int score, EventStatus status)
{
// Your module completion code here
SaveModuleProgress(moduleName);
// EventAssessmentComplete automatically advances to next module
// if in an auth-provided module sequence
Abxr.EventAssessmentComplete(moduleName, score, status);
}
Option 2: Adding Events to Each Module
If you don't have common wrappers, add EventAssessmentStart and EventAssessmentComplete calls directly in each module:
// At the start of each module
void Module_SafetyTraining()
{
Abxr.EventAssessmentStart("safety_training");
// ... module code ...
}
// At the end of each module
void CompleteSafetyTraining()
{
int score = CalculateScore();
Abxr.EventAssessmentComplete("safety_training", score, EventStatus.Pass);
}
Key Benefits:
EventAssessmentStartautomatically sets the module name in metadata when not in an auth-provided module sequence, ensuring the module is always sent to the serverEventAssessmentCompleteautomatically advances to the next module when in an auth-provided module sequence- Module metadata is automatically included in all subsequent events, logs, and telemetry
Tracking Sub-Tasks Within Modules:
For detailed tracking, also use EventObjectiveStart and EventObjectiveComplete for sub-tasks within each module:
// Track specific objectives within a module
Abxr.EventObjectiveStart("open_valve");
// ... user performs task ...
Abxr.EventObjectiveComplete("open_valve", 100, EventStatus.Complete);
// Track individual interactions
Abxr.EventInteractionStart("select_option_a");
Abxr.EventInteractionComplete("select_option_a", InteractionType.Select, InteractionResult.Correct, "true");
Event-Based Module Handling (For LMS Module Sequences)
To enable automatic module sequencing from LMS assignments, subscribe your deep link handler to the OnModuleTarget event. This allows the SDK to automatically route users through assigned modules. The event works perfectly with existing Android deep link handlers—you can use the same routing logic for both external deep links and LMS module targets. The module sequence executes automatically when authentication completes, and will wait for your subscription if needed, so you only need to subscribe to the event:
Features:
- Smart Automatic Execution: Module sequence executes automatically when authentication completes, and waits for your subscription if needed
- Event-Driven: Uses the
OnModuleTargetevent for maximum flexibility - Developer Control: You decide how to handle each module target
- Deep Link Integration: Perfect for connecting to existing deep link handlers
- Unified Handling: One method handles both external deep links and LMS module targets
- Error Handling: Continues to next module if an event handler throws an exception
- Return Count: Returns the number of successfully executed modules
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// Subscribe to module target events
Abxr.OnModuleTarget += HandleModuleOrDeepLinkTarget; // HandleModuleOrDeepLinkTarget points to your module/deep link handler
// Module(s) will be executed automatically when authentication completes!
// Create or use your own module/deep link handler along these lines
private void HandleModuleOrDeepLinkTarget(string moduleTarget)
{
Debug.Log($"Handling module target: {moduleTarget}");
// Your existing deep link routing logic works here too
switch (moduleTarget)
{
case "safety-training":
LoadScene("SafetyTrainingScene");
break;
case "equipment-check":
LoadScene("EquipmentCheckScene");
break;
default:
Debug.LogWarning($"Unknown module target: {moduleTarget}");
LoadScene("MainMenuScene");
break;
}
}
// Subscribe to module target events
Abxr.OnModuleTarget = (moduleTarget) => {
console.log(`Handling module target: ${moduleTarget}`);
// Your existing deep link routing logic works here too
switch (moduleTarget) {
case "safety-training":
loadScene("SafetyTrainingScene");
break;
case "equipment-check":
loadScene("EquipmentCheckScene");
break;
default:
console.warn(`Unknown module target: ${moduleTarget}`);
loadScene("MainMenuScene");
break;
}
};
// Module(s) will be executed automatically when authentication completes!
Note: Module Targets are supported in Unity and WebXR. Unreal Engine support is planned for future releases.
Manual Module Processing
For more control, you can manually process modules:
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// Get the next module target from available modules
CurrentSessionData nextTarget = Abxr.GetModuleTarget();
if (nextTarget != null)
{
Debug.Log($"Processing module: {nextTarget.moduleTarget}");
EnableModuleFeatures(nextTarget.moduleTarget);
NavigateToModule(nextTarget.moduleTarget);
}
else
{
Debug.Log("All modules completed!");
ShowCompletionScreen();
}
// Check remaining module count
int remaining = Abxr.GetModuleTargetCount();
Debug.Log($"Modules remaining: {remaining}");
// Get all available modules
var allModules = Abxr.GetModuleTargetList();
Debug.Log($"Total modules: {allModules.Count}");
// Reset progress
Abxr.ClearModuleTargets();
// Get current user information
var userData = Abxr.GetUserData();
// Get the next module target from available modules
const nextTarget = Abxr.GetModuleTarget();
if (nextTarget) {
console.log(`Processing module: ${nextTarget.moduleTarget}`);
enableModuleFeatures(nextTarget.moduleTarget);
navigateToModule(nextTarget.moduleTarget);
} else {
console.log("All modules completed!");
showCompletionScreen();
}
// Check remaining module count
const remaining = Abxr.GetModuleTargetCount();
console.log(`Modules remaining: ${remaining}`);
// Get all available modules
const allModules = Abxr.GetModuleTargetList();
console.log(`Total modules: ${allModules.length}`);
// Reset progress
Abxr.ClearModuleTargets();
// Get current user information
const userData = Abxr.GetUserData();
Note: Module Targets are supported in Unity and WebXR. Unreal Engine support is planned for future releases.
Persistence and Recovery
Module progress is automatically persisted across app sessions and device restarts:
- Session Persistence: Module progress survives app crashes and restarts
- Lazy Loading: Progress is automatically loaded from storage when first accessed
- Error Resilience: Failed storage operations are logged but don't crash the application
- Cross-Session Continuity: Users can continue multi-module experiences across sessions
Best Practices
- Use OnModuleTarget Event: Subscribe to
OnModuleTargetfor flexible module handling - Subscribe to OnAuthCompleted: Subscribe before authentication starts
- Connect to Deep Links: Use
OnModuleTargetto connect to your existing deep link handling - Error Handling: Handle cases where modules don't exist or fail
- Progress Tracking: Use assessment events to track module completion
- Unsubscribe on Destroy: Always unsubscribe from events in
OnDestroy()to prevent memory leaks
Data Structures
The module target callback provides a CurrentSessionData object with the following properties:
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
public class CurrentSessionData
{
public string moduleTarget; // The target module identifier from LMS
public object userData; // Additional user data from authentication
public object userId; // User identifier
public string userEmail; // User email address
}
interface CurrentSessionData {
moduleTarget: string; // The target module identifier from LMS
userData: any; // Additional user data from authentication
userId: string; // User identifier
userEmail: string; // User email address
}
Note: Module Targets are supported in Unity and WebXR. Unreal Engine support is planned for future releases.
Authentication
The ABXRLib SDK provides comprehensive authentication completion callbacks that deliver detailed user and module information. This enables rich post-authentication workflows including automatic module navigation and personalized user experiences.
Authentication Completion Event
If you would like to have logic to correspond to authentication completion, you can subscribe to this event.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// 'true' for success and 'false' for failure (string argument will contain the error message on failure)
public static Action<bool, string> OnAuthCompleted;
// Example usage
Abxr.OnAuthCompleted += (success, errorMessage) => {
if (success) {
Debug.Log("Authentication successful!");
// Initialize your app features here
StartGameFlow();
} else {
Debug.LogError($"Authentication failed: {errorMessage}");
// Handle authentication failure
ShowLoginScreen();
}
};
// Subscribe to authentication events to receive user information and module targets
UAbxr::OnAuthCompleted.AddDynamic(this, &AMyActor::HandleAuthCompleted);
// In your actor's header file (.h):
UFUNCTION()
void HandleAuthCompleted(const FAuthCompletedData& AuthData);
// In your actor's implementation file (.cpp):
void AMyActor::HandleAuthCompleted(const FAuthCompletedData& AuthData)
{
if (AuthData.bSuccess)
{
UE_LOG(LogTemp, Log, TEXT("Welcome %s!"), *AuthData.UserEmail);
// Handle initial vs reauthentication
if (AuthData.bIsReauthentication)
{
RefreshUserData();
}
else
{
InitializeUserInterface();
}
// Navigate to module if specified
if (!AuthData.ModuleTarget.IsEmpty())
{
NavigateToModule(AuthData.ModuleTarget);
}
}
}
// Subscribe to authentication completion - the recommended approach
Abxr.OnAuthCompleted = (authData) => {
if (authData.success) {
console.log("Authentication successful - AbxrLib is ready!");
console.log(`Welcome ${authData.userEmail}!`);
// Initialize your app features here
startGameFlow();
} else {
console.error(`Authentication failed: ${authData.error}. Working in offline mode`);
// Initialize your app features here
startGameFlow();
}
};
Use Cases
- Post-authentication setup: Initialize UI components and load user preferences
- Module navigation: Automatically direct users to specific LMS assignments
- Personalization: Customize experience based on user data
- Session management: Handle reauthentication vs initial authentication differently
- Error handling: Respond appropriately to authentication failures
Connection Status Check
You can check if AbxrLib has an active connection to the server at any time:
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
//C# Method Signature
public static bool Abxr.ConnectionActive()
// Example usage
// Check app-level connection status
if (Abxr.ConnectionActive())
{
Debug.Log("AbxrLib is connected and ready to send data");
Abxr.Event("app_ready");
}
else
{
Debug.Log("Connection not active - waiting for authentication");
Abxr.OnAuthCompleted += (success, error) => {
if (success) {
Debug.Log("Connection established successfully!");
}
};
}
// Conditional feature access
if (Abxr.ConnectionActive())
{
ShowConnectedFeatures();
SendTelemetryData();
}
else
{
UseOfflineMode();
}
Returns: Boolean indicating if the library has an active connection and can communicate with the server (app-level authentication status)
Use Cases:
- Conditional logic: Only send events/logs when connection is active
- UI state management: Show online/offline status indicators
- Error prevention: Check connection before making API calls
- Feature gating: Enable/disable features that require server communication
// C++ Method Signature
bool UAbxr::ConnectionActive();
// Example usage
// Check app-level connection status
if (UAbxr::ConnectionActive())
{
UE_LOG(LogTemp, Log, TEXT("AbxrLib is connected and ready to send data"));
UAbxr::Event(TEXT("app_ready"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("Connection not active - waiting for authentication"));
UAbxr::OnAuthCompleted.AddDynamic(this, &AMyActor::HandleAuthCompleted);
}
// Conditional feature access
if (UAbxr::ConnectionActive())
{
ShowConnectedFeatures();
SendTelemetryData();
}
else
{
UseOfflineMode();
}
Returns: Boolean indicating if the library has an active connection and can communicate with the server (app-level authentication status)
// JavaScript Method Signature
static ConnectionActive(): boolean
// Example usage
// Check app-level connection status
if (Abxr.ConnectionActive()) {
console.log("AbxrLib is connected and ready to send data");
Abxr.Event("app_ready");
} else {
console.log("Connection not active - waiting for authentication");
Abxr.OnAuthCompleted = (authData) => {
if (authData.success) {
console.log("Connection established successfully!");
}
};
}
// Conditional feature access
if (Abxr.ConnectionActive()) {
showConnectedFeatures();
sendTelemetryData();
} else {
useOfflineMode();
}
Returns: Boolean indicating if the library has an active connection and can communicate with the server (app-level authentication status)
Headset Removal
To improve session fidelity and reduce user spoofing or unintended headset sharing, the SDK triggers a re-authentication prompt when the headset is taken off and then put back on mid-session. If the headset is put on by a new user, this will trigger an event that you can subscribe to:
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
public static Action OnHeadsetPutOnNewSession;
// Example usage
Abxr.OnHeadsetPutOnNewSession += () => {
Debug.Log("New user detected - headset was put on by someone else");
// Handle new user scenario
ShowUserSwitchPrompt();
};
// Subscribe to headset removal events
UAbxr::OnHeadsetPutOnNewSession.AddDynamic(this, &AMyActor::HandleNewUser);
// In your actor's header file (.h):
UFUNCTION()
void HandleNewUser();
// In your actor's implementation file (.cpp):
void AMyActor::HandleNewUser()
{
UE_LOG(LogTemp, Log, TEXT("New user detected - headset was put on by someone else"));
// Handle new user scenario
ShowUserSwitchPrompt();
}
// Subscribe to headset removal events
Abxr.OnHeadsetPutOnNewSession = () => {
console.log("New user detected - headset was put on by someone else");
// Handle new user scenario
showUserSwitchPrompt();
};
Session Management
The ABXRLib SDK provides comprehensive session management capabilities that allow you to control authentication state and session continuity. These methods are particularly useful for multi-user environments, testing scenarios, and creating seamless user experiences across devices and time.
StartNewSession
Start a new session with a fresh session identifier. This method generates a new session ID and performs fresh authentication, making it ideal for starting new training experiences or resetting user context.
Use Cases:
- Starting new training modules or courses
- Resetting user progress for a fresh start
- Creating separate sessions for different users on the same device
- Beginning new assessment attempts
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
//C# Method Signature
public static void Abxr.StartNewSession()
// Example Usage
Abxr.StartNewSession();
// C++ Method Signature
void UAbxr::StartNewSession();
// Example Usage
UAbxr::StartNewSession();
// JavaScript Method Signature
static StartNewSession(): void
// Example Usage
Abxr.StartNewSession();
ReAuthenticate
Trigger manual reauthentication with existing stored parameters. This method is primarily useful for testing authentication flows or recovering from authentication issues.
Use Cases:
- Testing authentication flows during development
- Recovering from authentication errors
- Refreshing expired credentials
- Debugging authentication issues
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
//C# Method Signature
public static void Abxr.ReAuthenticate()
// Example Usage
Abxr.ReAuthenticate();
// C++ Method Signature
void UAbxr::ReAuthenticate();
// Example Usage
UAbxr::ReAuthenticate();
// JavaScript Method Signature
static ReAuthenticate(): void
// Example Usage
Abxr.ReAuthenticate();
Note: All session management methods work asynchronously and will trigger the OnAuthCompleted event when authentication completes, allowing you to respond to success or failure states.
Debug Window
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
The Debug Window is a little bonus feature from the AbxrLib developers. To help with general debugging, this feature routes a copy of all AbxrLib messages (Logs, Events, etc) to a window within the VR space. This enables developers to view logs in VR without having to repeatedly take on and off your headset while debugging.
To use this feature, simply drag the AbxrDebugWindow Prefab from AbxrLib for Unity/Resources/Prefabs, to whatever object in the scene you want this window attached to (i.e. Left Controller).
Note: Debug window support is planned for a future release
For debugging authentication, network issues, or other problems, enable debug logging:
// Check if connection is established with the service
Abxr.ConnectionActive();
// Enable and check debug mode Method Signatures
Abxr.SetDebugMode(enabled)
Abxr.GetDebugMode()
// Example usage
Abxr.SetDebugMode(true); // Enable debug logging
Abxr.SetDebugMode(false); // Disable debug logging
const isDebugging = Abxr.GetDebugMode();
console.log('Debug mode:', isDebugging);
// Conditional debug setup for development
if (process.env.NODE_ENV === 'development') {
Abxr.SetDebugMode(true);
}
Parameters:
enabled(boolean): Enable or disable debug mode
Returns: GetDebugMode() returns boolean indicating current debug state
Debug Mode Benefits:
- Detailed error messages: See exactly what's failing during authentication
- Network request logging: Track API calls and responses
- State information: Monitor internal library state changes
- Performance insights: Identify bottlenecks and timing issues
ArborXR Device Management
These methods provide access to device-level information and SSO authentication status on ArborXR-managed devices. These are convenience methods that operate at the device level, separate from the app-level authentication managed by the ABXRLib SDK.
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// Device Information Methods
string deviceId = Abxr.GetDeviceId(); // UUID assigned to device by ArborXR
string deviceTitle = Abxr.GetDeviceTitle(); // Title given to device by admin
string deviceSerial = Abxr.GetDeviceSerial(); // Serial assigned to device by OEM
string[] deviceTags = Abxr.GetDeviceTags(); // Tags added to device by admin
// Organization Information
string orgId = Abxr.GetOrgId(); // UUID of the organization
string orgTitle = Abxr.GetOrgTitle(); // Name assigned to organization
string orgSlug = Abxr.GetOrgSlug(); // Identifier generated by ArborXR
// Network Information
string macFixed = Abxr.GetMacAddressFixed(); // Physical MAC address
string macRandom = Abxr.GetMacAddressRandom(); // Randomized MAC address for WiFi
// Authentication Status
bool isAuthenticated = Abxr.GetIsAuthenticated(); // Whether device is SSO authenticated
string accessToken = Abxr.GetAccessToken(); // SSO access token
string refreshToken = Abxr.GetRefreshToken(); // SSO refresh token
DateTime expiresDate = Abxr.GetExpiresDateUtc(); // When SSO access token expires
string fingerprint = Abxr.GetFingerprint(); // Device fingerprint
Note: ArborXR Device Management is currently only available in Unity. Unreal Engine support is planned for future releases.
Note: ArborXR Device Management is not available for WebXR support.
Mixpanel Compatibility
The ABXRLib SDK provides full compatibility with Mixpanel's tracking patterns, making migration simple and straightforward. You can replace your existing Mixpanel tracking calls with minimal code changes while gaining access to ABXR's advanced XR analytics capabilities.
Why Migrate from Mixpanel?
- XR-Native Analytics: Purpose-built for spatial computing and immersive experiences
- Advanced Session Management: Resume training across devices and sessions
- Enterprise Features: LMS integrations, SCORM/xAPI support, and AI-powered insights
- Spatial Tracking: Built-in support for 3D position data and XR interactions
- Open Source: No vendor lock-in, deploy to any backend service
Migration Steps:
- Remove Mixpanel references from your project
- Configure ABXRLib SDK credentials in your project settings
- Replace Mixpanel tracking calls with ABXRLib equivalents throughout codebase
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// Mixpanel → ABXR migration example
// Before: Mixpanel.Track("Plan Selected", props);
// After: Abxr.Track("Plan Selected", props);
//
// Before: var props = new Value();
// After: var props = new Abxr.Value();
//C# Method Signatures
public static void Abxr.Track(string eventName);
public static void Abxr.Track(string eventName, Abxr.Value properties);
public static void Abxr.Track(string eventName, Dictionary<string, object> properties);
// Abxr.Value class for Mixpanel compatibility
var props = new Abxr.Value();
props["amount"] = 29.99;
props["currency"] = "USD";
// Track methods (exactly like Mixpanel)
Abxr.Track("user_signup");
Abxr.Track("purchase_completed", props);
// Timed events
Abxr.StartTimedEvent("puzzle_solving");
// ... later ...
Abxr.Track("puzzle_solving"); // Duration automatically included
// Super Meta Data (equivalent to Mixpanel's Super Properties)
Abxr.Register("user_type", "premium"); // Set persistent "super metadata "
Abxr.RegisterOnce("app_version", "1.2.3"); // Set only if not already set
Abxr.Reset(); // Clear all super metadata
// Mixpanel → ABXR migration example
// Before: Mixpanel->Track("Plan Selected", Properties);
// After: UAbxr::Track(TEXT("Plan Selected"), Properties);
//C++ Method Signatures
public static void UAbxr::Track(const FString& EventName);
public static void UAbxr::Track(const FString& EventName, TMap<FString, FString>& Properties);
// ABXR compatibility methods for Mixpanel users
UAbxr::Track(TEXT("user_signup"));
TMap<FString, FString> Properties;
Properties.Add(TEXT("amount"), TEXT("29.99"));
Properties.Add(TEXT("currency"), TEXT("USD"));
UAbxr::Track(TEXT("purchase_completed"), Properties);
// Timed events
UAbxr::StartTimedEvent(TEXT("puzzle_solving"));
// ... later ...
UAbxr::Track(TEXT("puzzle_solving")); // Duration automatically included
// Mixpanel → ABXR migration example
// Before: mixpanel.track("Plan Selected", properties);
// After: Abxr.Track("Plan Selected", properties);
// JavaScript Method Signatures
static async Track(eventName: string, properties?: any): Promise<number>
// ABXR compatibility methods for Mixpanel users
Abxr.Track("user_signup");
const properties = {
amount: 29.99,
currency: "USD"
};
Abxr.Track("purchase_completed", properties);
// Timed events
Abxr.StartTimedEvent("puzzle_solving");
// ... later ...
Abxr.Track("puzzle_solving"); // Duration automatically included
Key Advantages Over Mixpanel
| Feature | Mixpanel | ABXRLib SDK |
|---|---|---|
| Basic Event Tracking | ✅ | ✅ |
| Custom Properties | ✅ | ✅ |
| Super Metadata/Properties | ✅ | ✅ (Register/RegisterOnce available) |
| Timed Events | ✅ | ✅ (StartTimedEvent available) |
| 3D Spatial Data | ❌ | ✅ (Built-in Vector3 support) |
| XR-Specific Events | ❌ | ✅ (Assessments, Interactions, Objectives) |
| Session Persistence | Limited | ✅ (Cross-device, resumable sessions) |
| Enterprise LMS Integration | ❌ | ✅ (SCORM, xAPI, major LMS platforms) |
| Real-time Collaboration | ❌ | ✅ (Multi-user session tracking) |
| Open Source | ❌ | ✅ |
Migration: Simply replace Mixpanel calls with ABXRLib equivalents throughout your codebase.
Cognitive3D Compatibility
The ABXRLib SDK provides compatibility with most of the Cognitive3D SDK, allowing you to either migrate from Cognitive3D or use both libraries side-by-side. You can add or migrate to ABXRLib from existing Cognitive3D implementations with minimal code changes while gaining access to ABXR's advanced XR analytics capabilities and LMS integrations.
Note: Enums are also available in the global namespace as
AbxrEventStatus,AbxrInteractionType,AbxrInteractionResult,AbxrLogLevel,AbxrStorageScope, andAbxrStoragePolicyfor compatibility, but the recommended approach is to use theAbxr.*namespace to avoid conflicts.
Why Add ABXRLib to Your Cognitive3D Setup?
- LMS Integration: Native LMS platform support with SCORM/xAPI compatibility
- Advanced Analytics: Purpose-built dashboards for learning and training outcomes
- Enterprise Features: Session management, cross-device continuity, and AI-powered insights
- Open Source: No vendor lock-in, deploy to any backend service
- Structured Events: Rich event wrappers for assessments, objectives, and interactions
- Side-by-Side Usage: Keep your existing Cognitive3D implementation while adding ABXR features
Migration Overview
There are a few options for migration or combined usage:
Option 1: Quick Migration If you want to replace Cognitive3D entirely, migration can be as simple as the following steps.
Step 1: Disable using statement
// Before: using Cognitive3D;
// After: //using Cognitive3D;
Step 2: Replace "Cognitive3D." with "Abxr." throughout your codebase to use the compatibility methods
// Before (Cognitive3D):
new Cognitive3D.CustomEvent("Pressed Space").Send();
// After (ABXRLib) - Direct replacement:
new Abxr.CustomEvent("Pressed Space").Send();
Option 2: Side-by-Side Usage Keep your existing Cognitive3D implementation and add ABXRLib for enhanced features:
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
// Your existing Cognitive3D code stays unchanged, and then add the Abxr version right below
new Cognitive3D.CustomEvent("Pressed Space").Send();
new Abxr.CustomEvent("Pressed Space").Send();
// Both libraries work side-by-side seamlessly
Cognitive3D.StartEvent("final_exam");
Abxr.EventAssessmentStart("final_exam"); // Enhanced LMS integration
// Later...
Cognitive3D.EndEvent("final_exam", "pass", 95);
Abxr.EventAssessmentComplete("final_exam", 95, EventStatus.Pass); // Structured data
// Your existing Cognitive3D code stays unchanged, and then add the Abxr version right below
new Cognitive3D.CustomEvent("Pressed Space").Send();
new Abxr.CustomEvent("Pressed Space").Send();
// Both libraries work side-by-side seamlessly
Cognitive3D.StartEvent("final_exam");
Abxr.EventAssessmentStart("final_exam"); // Enhanced LMS integration
// Later...
Cognitive3D.EndEvent("final_exam", "pass", 95);
Abxr.EventAssessmentComplete("final_exam", 95, Abxr.EventStatus.Pass); // Structured data
Note: Cognitive3D Compatibility is supported in Unity and WebXR. Unreal Engine support is not available.
Cognitive3D vs ABXRLib
| Feature | Cognitive3D | ABXRLib SDK |
|---|---|---|
| Spatial Analytics | ✅ | ❌ |
| Basic Event Tracking | ✅ | ✅ |
| Custom Properties | ✅ | ✅ |
| Session Properties | ✅ | ✅ (Enhanced with persistence) |
| LMS Integration | ❌ | ✅ (SCORM, xAPI, major platforms) |
| Structured Learning Events | ❌ | ✅ (Assessments, Objectives, Interactions) |
| Cross-Device Sessions | ❌ | ✅ (Resume training across devices) |
| AI-Powered Insights | ❌ | ✅ (Content optimization, learner analysis) |
| Open Source | ❌ | ✅ |
Dialog Customization
The SDK has built-in dialogs to support two-step authentication when the backend requires additional credentials (like a PIN or email).
- Unity (C#)
- Unreal Engine (C++)
- WebXR (TypeScript)
Note: In the configuration panel you can provide your own prefabs. More details to come.
Note: Dialog Customization for Unreal Engine is planned for future releases.
There are multiple approaches to handle this:
Option 1: Built-in Dialog System (Recommended)
NEW: Zero-code authentication with beautiful, XR-optimized dialogs! Perfect for VR/AR developers:
import { Abxr_init } from 'abxrlib-for-webxr';
// Simple initialization - XR dialog appears automatically when needed
Abxr_init('app123', 'org456', 'secret789');
// That's it! The library handles everything:
// - Auto-detects XR environments vs regular browsers
// - Shows beautiful XR-optimized dialogs in VR/AR
// - Includes virtual keyboards for XR environments
// - Falls back to HTML dialogs for regular browsers
// - Handles all auth types (email, PIN, etc.) automatically
Option 2: Customize Styling of Built-in Dialog System
const dialogOptions = {
enabled: true,
type: 'xr', // 'html', 'xr', or 'auto' (default)
xrFallback: true, // Fallback to HTML if XR fails
xrStyle: {
colors: {
primary: '#00ffff', // Cyan accent
success: '#00ff88', // Green submit button
background: 'linear-gradient(135deg, #0a0a0a, #1a1a2e)',
keyBg: 'rgba(0, 255, 255, 0.1)', // Virtual keyboard keys
keyText: '#ffffff',
keyActive: '#00ffff'
},
dialog: {
borderRadius: '20px',
border: '3px solid #00ffff',
boxShadow: '0 0 50px rgba(0, 255, 255, 0.5)'
},
overlay: {
background: 'radial-gradient(circle, rgba(0, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.9) 100%)'
}
}
};
Abxr_init('app123', undefined, undefined, undefined, dialogOptions);
What makes XR dialogs special:
- 🥽 VR/AR Optimized: Beautiful in both desktop browsers and XR headsets
- ⌨️ Virtual Keyboard: Built-in keyboard for XR environments (PIN pad for PINs)
- 🎨 Fully Customizable: Colors, styling, and behavior - match your brand
- 🔄 Auto-Detection: Automatically chooses XR vs HTML dialog based on environment
- 📱 Universal: Works everywhere - desktop, mobile, and XR devices
Option 3: Custom Callback Approach
For developers who want to provide their own authentication UI:
import { Abxr_init, Abxr, AuthMechanismData } from 'abxrlib-for-webxr';
// Define callback to handle authentication requirements
function handleAuthMechanism(authData: AuthMechanismData) {
console.log('Auth required:', authData.type); // e.g., 'email', 'assessmentPin'
console.log('Prompt:', authData.prompt); // e.g., 'Enter your Email'
console.log('Domain:', authData.domain); // e.g., 'acme.com' (for email type)
// Show UI to collect user input
const userInput = prompt(authData.prompt);
// Format and submit authentication data
const formattedAuthData = Abxr.formatAuthDataForSubmission(userInput, authData.type, authData.domain);
Abxr.completeFinalAuth(formattedAuthData).then(success => {
if (success) {
console.log('Authentication complete');
} else {
console.log('Authentication failed');
}
});
}
// Initialize with callback
Abxr_init('app123', undefined, undefined, undefined, undefined, handleAuthMechanism);
Option 4: Manual Check Approach
Check for additional authentication requirements manually (for advanced use cases):
import { Abxr_init, Abxr } from 'abxrlib-for-webxr';
// Step 1: Initial authentication
Abxr_init('app123', 'org456', 'secret789');
// Step 2: Check if additional authentication is required
if (Abxr.getRequiresFinalAuth()) {
console.log('Additional authentication required');
// Extract structured auth data
const authData = Abxr.extractAuthMechanismData();
if (authData) {
console.log('Auth type:', authData.type); // e.g., 'email', 'assessmentPin'
console.log('Prompt:', authData.prompt); // e.g., 'Enter your Email'
console.log('Domain:', authData.domain); // e.g., 'acme.com'
// Get user input
const userInput = prompt(authData.prompt);
// Format and submit
const formattedData = Abxr.formatAuthDataForSubmission(userInput, authData.type, authData.domain);
const success = await Abxr.completeFinalAuth(formattedData);
if (success) {
console.log('Authentication complete');
}
}
}
AuthMechanism Types
The SDK supports various authentication types:
email: Email-based authentication with domain supportassessmentPin: PIN-based authentication for assessments- Custom types: As defined by your backend service
Helper Methods
Abxr.extractAuthMechanismData()- Get structured auth requirementsAbxr.formatAuthDataForSubmission(input, type, domain?)- Format user input for submissionAbxr.getRequiresFinalAuth()- Check if additional auth is requiredAbxr.completeFinalAuth(authData)- Submit final authentication credentials
Support
Resources
- Docs: https://help.arborxr.com/
- GitHub Unity: https://github.com/ArborXR/abxrlib-for-unity
- GitHub Unreal: https://github.com/ArborXR/abxrlib-for-unreal
- GitHub WebXR: https://github.com/ArborXR/abxrlib-for-webxr
FAQ
How do I retrieve my Application ID and Authorization Secret?
Your Application ID can be found in the ArborXR Portal under the application details (you must be sure to use the App ID from the specific application you need data sent through). For the Authorization Secret, navigate to Settings > Organization Codes on the same portal.
How do I enable object tracking?
Object tracking can be enabled by adding the Track Object component to any GameObject in your scene via the Unity Inspector.
Which platforms support which features?
| Feature | Unity | Unreal | WebXR |
|---|---|---|---|
| Basic Event Tracking | ✅ | ✅ | ✅ |
| Analytics Event Wrappers | ✅ | ✅ | ✅ |
| Timed Events | ✅ | ✅ | ✅ |
| Super Meta Data | ✅ | ✅ | ✅ |
| Logging | ✅ | ✅ | ✅ |
| Storage | ✅ | ✅ | ✅ |
| Telemetry | ✅ | ✅ | ✅ |
| AI Integration | ✅ | ✅ | ✅ |
| Exit Polls | ✅ | ✅ | ✅ |
| Module Targets | ✅ | 🔄 Planned | ✅ |
| Authentication | ✅ | ✅ | ✅ |
| Headset Removal | ✅ | ✅ | ✅ |
| Session Management | ✅ | ✅ | ✅ |
| Debug Window | ✅ | 🔄 Planned | ❌ |
| Debug Mode | ❌ | ❌ | ✅ |
| ArborXR Device Management | ✅ | 🔄 Planned | 🔄 Planned |
| Mixpanel Compatibility | ✅ | ✅ | ✅ |
| Cognitive3D Compatibility | ✅ | ❌ | ✅ |
| Dialog Customization | ✅ | 🔄 Planned | ✅ |
Legend: ✅ Supported | 🔄 Planned | ❌ Not Available
Troubleshooting
Problem: Library fails to authenticate
- Solution: Verify your App ID, Org ID, and Auth Secret are correct in your project settings
- Check: Ensure all three credentials are entered in your platform's configuration
- Debug: Check the console/logs for detailed ABXR authentication error messages
Problem: Events not being sent
- Solution: Verify authentication completed successfully during app startup
- Debug: Monitor the console/logs for ABXR connection status messages
- Check: Ensure your event names use snake_case format for best processing
Problem: Library works in editor but not in packaged builds
- Solution: For production builds, only include App ID in project settings
- Check: Remove Org ID and Auth Secret from packaged builds distributed to third parties
- Alternative: Use ArborXR-managed devices where credentials are automatically provided
Problem: Missing credentials on non-managed devices
- Solution: Ensure all three credentials (App ID, Org ID, Auth Secret) are configured for development/testing
- Check: Verify credentials are correctly entered in your platform's project settings
- Debug: Check that the configuration is properly saved with the project