Skip to main content

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

  1. Introduction
  2. Installation
  3. Configuration
  4. Quick Start Guide
  5. Sending Data
  6. Advanced Features
  7. Support

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

  1. Open Unity and go to Window > Package Manager.
  2. Select the '+' dropdown and choose 'Add package from git URL'.
  3. Use the GitHub repo URL:
    https://github.com/ArborXR/abxrlib-for-unity.git
  4. Once imported, you will see Analytics for XR in your Unity toolbar.

Configuration

Using with ArborXR Insights

To use the ABXRLib SDK with ArborXR Insights:

Get Your Credentials

  1. Go to the ArborXR Portal and log in.
  2. 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 ID and Auth Secret directly 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.

  1. Open Analytics for XR > Configuration in the Unity Editor.
  2. For Development/Testing: Paste in the App ID, Org ID, and Auth Secret. All 3 are required if you are testing from Unity itself.
  3. 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.

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

//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.Dict to avoid requiring using statements
  • location_data parameter is a Vector3

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

Score range (score_min / score_max)

The score parameter in EventAssessmentComplete (and EventObjectiveComplete) is interpreted against a default range of 0–100. If your assessment uses a different scale (e.g. 0–400, 1–10, or 0–50), you must pass score_min and score_max in the meta dictionary so the SDK and reporting use the correct range. If you omit them and pass a score outside 0–100, the SDK will clamp the score to the default range and log a warning—watch for these warnings during testing to fix the integration before production.

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.

// 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");

Additional Event Wrappers

//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");

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. Score range defaults to 0–100. If your scoring scale is different (e.g. 0–400, or 1–10), you must pass score_min and score_max in the meta parameter so the SDK and dashboards interpret the score correctly. If you omit them and the provided score is outside 0–100, the SDK will clamp the score to the default range and log a warning (visible during testing).
  • meta: For EventAssessmentComplete (and EventObjectiveComplete when scored), you can set score_min and score_max (snake_case; integers as strings, e.g. "0", "100") to define the valid range. Use these when your scale is not 0–100.
  • result (InteractionResult / interaction outcome): How the learner’s answer or action should be interpreted for analytics and LMS mapping (correct, incorrect, neutral). The SDK serializes this into event meta as lowercase result.
  • response (string): The learner’s response payload (e.g. selected option id, "true"/"false", free text). Serialized into meta as response when non-empty. Prefer stable, machine-friendly values (e.g. option_a or a,c) over display-only labels when possible.
  • type (InteractionType): The interaction pattern (Bool, Select, Text, etc.). Serialized into meta as interaction (lowercase).
  • meta (Dictionary<string, string> or Abxr.Dict): Optional. Additional key-value pairs merged into the event. Use Abxr.Dict in Unity to avoid extra using directives. Values are strings in the wire format; use snake_case for custom keys so they align with collect/LMS conventions and future dashboards.

Note: All complete events automatically calculate duration if a corresponding start event was logged.

Insights stores structured fields inside each event’s meta object. Using consistent key names and value vocabularies across titles lets ArborXR ship shared dashboard templates (correctness breakdowns, item analysis, time-on-task, etc.) without custom work per app. Some keys are already interpreted by the collect / transformation pipeline (see your backend “collect” reference); others are conventions you can adopt now so data is ready as analytics features land.

General rules

  • Prefer snake_case for names you add (content_version, attempt_count).
  • Keep enumerated values stable: use the same spelling forever for a given meaning (correct / incorrect / neutral, difficulty tiers, phase names).
  • Do not put PII in metadata unless your privacy review requires it; use opaque ids (e.g. content_item_id). Data such as names or emails belong in user data via Abxr.SetUserData().
  • If you change key names or value meanings mid-deployment, historical dashboards will break for that content—treat keys like a public API.

Interaction events — pipeline-oriented keys

These align with the collect reference for interaction events. The Unity/Unreal/WebXR APIs map response, result, and interaction type into meta automatically when you use the interaction helpers; you can still duplicate or supplement them in meta if needed.

KeyTypical useValue guidance
responseWhat the learner submittedMatch the interaction type: Bool / Select / Text / Number / Rating patterns expected by collect (e.g. comma-separated options for multi-select).
resultCorrectness / grading outcomecorrect, incorrect, or neutral (lowercase in stored payloads).
interactionInteraction patterne.g. bool, select, text, number, rating, matching, performance, sequencing (SDKs may set this from InteractionType).
weightingImportance of this item in scoringPositive number; fine-grained decimals allowed (see collect validation). Default handling may assume 1.0 when missing.
descriptionHuman-readable prompt or item labelShort string describing the task or question (for dashboards and exports, not a substitute for LMS item banks).
durationTime on this interactionUsually set automatically when you pair start and complete; can be overridden if you measure differently.

Categorization (assessment, objective, interaction, or generic events)

KeyTypical use
categoryTop-level curriculum or product area (e.g. safety, onboarding).
sub_categoryModule or lesson group.
sub_sub_categoryFine-grained topic or chapter.
tagsComma-separated or structured list of labels for filtering (agree on delimiter in your org).

Optional extensions (common training metrics)

Beyond the pipeline keys above, these six are enough for most learning content: they support mastery and remediation, rollout comparisons, and filtering without replacing response / result for graded items. Use assessment, objective, and interaction event names (and the description field when you need a human-readable label) instead of duplicating identifiers that would only repeat those names.

KeyWhy it mattersExample values
attempt_countRetries before success—standard for engagement and mastery signals.1, 2
hints_usedScaffolding usage—how much support the learner needed.0, 3
difficultyDesigned difficulty tier—compare performance across levels.beginner, intermediate, advanced
error_typeWhen result is incorrect, a stable label for the mistake (remediation and error dashboards).wrong_sequence, wrong_tool, timeout
session_phaseInstructional mode—separates practice from summative checks.tutorial, practice, assessment, remediation

You can add other keys for your product (e.g. spatial or build identifiers); only the names above are prioritized for shared dashboard patterns.

Custom events (Event / Track)

Use the same optional keys where they fit. Prefer event names that describe behavior (tool_selected, valve_turned) and add category / tags so ad-hoc events stay filterable alongside assessments and interactions.

Backend support

Some keys are validated or transformed in lib-backend collect paths; others are stored and surfaced for reporting as-is. Treat this section as the contract you want as a developer; platform features will increasingly assume these names when present.

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.

//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

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:

// 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");

Super Meta Data

Global metadata automatically included in all events, logs, and telemetry data.

//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

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.

//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"}
});

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.

//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> or Abxr.Dict): The key-value pairs to store. Use Abxr.Dict to 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.

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.

//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> or Abxr.Dict): Key-value pairs of telemetry measurements. Use Abxr.Dict to avoid requiring using statements.

AI Integration

The AI Integration methods provide access to AI services for enhanced user interactions and experiences within XR environments.

// 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.

Exit Polls

Deliver questionnaires to users to gather feedback.

// 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);

Metadata Formats

The ABXRLib SDK supports multiple flexible metadata formats. All formats are automatically converted to key-value pairs:

// 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.Dict for 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

Advanced Features

Workflow options (LMS and PIN)

When you use ABXRLib with ArborXR Insights, you get data collection and integration with LMS products used by schools and HR. The assessment PIN workflow supports this sequence:

  1. Learner: Gets their PIN at the LMS (e.g. from an assignment or course).
  2. Learner: Puts on the headset, from home screen they launch the specified app.
  3. Learner: Sees the PIN dialog (built-in or your custom UI).
  4. Learner: Enters the PIN (or uses Guest Access to bypass LMS tracking when desired).
  5. Learner: Completes the training (or the specific module when the LMS assigns one).
  6. LMS receives the data and the assignment shows as complete.
  7. Headset is back at home screen ready for the next user.

Learner Launcher workflow

Learner Launcher mode from ArborXR reduces user friction and opportunity for error by removing the step that requires learners to choose which app to launch from the list of apps on the home screen. With Learner Launcher, the flow is:

  1. Learner: Gets their PIN at the LMS (e.g. from an assignment or course).
  2. Learner: Puts on the headset and sees the PIN dialog (They have no other choices—no apps to choose from, nothing else but the PIN dialog).
  3. Learner: Enters their PIN.
  4. The app specified in the LMS connection gets launched, including the module if configured.
  5. Learner: Completes the training (or the specific module when the LMS assigns one).
  6. LMS receives the data and the assignment shows as complete.
  7. Headset is at PIN dialog ready for the next learner.

If your app shows initial dialogs before the PIN (e.g. login, trial, or signup), see When your app shows initial dialogs before the PIN so the PIN dialog does not block the user. For module-based assignments, when the user finishes their assigned module(s), you can return them to the home screen with a fresh PIN prompt so the headset is ready for the next user.

Module Targets

In the SDK and Insights, module means a discrete unit of training inside your application (assessment boundaries, LMS assignments, and moduleName parameters on events). Your authoring pipeline or content may call that same unit a scenario, a scene, or a lesson—those are fine as product terms; configuration and APIs still use module (GetModuleList(), module targets, automatic module metadata on events).

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.

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:

  • EventAssessmentStart automatically sets the module name in metadata when not in an auth-provided module sequence, ensuring the module is always sent to the server
  • EventAssessmentComplete automatically 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 OnModuleTarget event 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
// 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;
}
}

Best Practices

  1. Use OnModuleTarget Event: Subscribe to OnModuleTarget for flexible module handling
  2. Subscribe to OnAuthCompleted: Subscribe before authentication starts
  3. Connect to Deep Links: Use OnModuleTarget to connect to your existing deep link handling
  4. Error Handling: Handle cases where modules don't exist or fail
  5. Progress Tracking: Use assessment events to track module completion
  6. Unsubscribe on Destroy: Always unsubscribe from events in OnDestroy() to prevent memory leaks

Completion flow: return to home with fresh PIN prompt

When the LMS assigns a specific module and the user completes it, returning them to the home screen with a new PIN dialog gives a clear handoff for the next user (or the same user with a new assignment). Use Abxr.OnAllModulesCompleted to run your own logic when all assigned modules are done:

  1. Subscribe to Abxr.OnAllModulesCompleted with a handler.
  2. In the handler: call Abxr.EndSession(), direct the user to your home screen, then call Abxr.StartNewSession().

Resulting flow: User gets PIN at LMS → Puts on headset → Sees PIN dialog → Enters PIN → Is navigated to the correct module → Completes training → Returns to main screen with a new PIN dialog. The headset is ready for the next user, or the same user can get their next assignment and PIN from the LMS. This pattern mainly affects users who were initially assigned a specific module to complete.

// Subscribe early (e.g. in Start or Awake)
Abxr.OnAllModulesCompleted += OnAllModulesCompleted_Handler;

void OnAllModulesCompleted_Handler()
{
Abxr.EndSession();
// Navigate user to your home screen (e.g. LoadScene, show main menu)
GoToHomeScreen();
Abxr.StartNewSession();
}

void OnDestroy()
{
Abxr.OnAllModulesCompleted -= OnAllModulesCompleted_Handler;
}

Authentication

By default, the ABXRLib SDK authenticates immediately when starting the app. If you would like to delay the authentication process, you have two configuration settings you can use. The first is 'Enable Auto Start Authentication'. If 'Enable Auto Start Authentication' is checked, you then have the option to delay the start with the config setting 'Authentication Start Delay (seconds)'. If 'Enable Auto Start Authentication' is not checked, then you will have to call Abxr.StartAuthentication() to start authentication process.

When your app shows initial dialogs before the PIN

If your app shows its own dialogs when it launches (e.g. login, trial, or signup), and the ArborXR portal Headset Login Policy is anything other than "None," the SDK’s PIN/keyboard can appear in front of your dialogs and block progress.

Solution — Take controlof when user authentication starts:

  1. In Unity: Analytics for XR → Configuration. Under Authentication Control, uncheck Enable Auto Start Authentication.
  2. In your code, after the user completes your initial step, call Abxr.StartAuthentication().

The PIN dialog (or your custom auth UI) will then appear only after the user has passed your initial step. You can still use the same LMS and PIN workflow once authentication starts.

Abxr.StartAuthentication();

Primary user identifier (GetUserId / SetUserId)

Use GetUserId() and SetUserId() when you need the single value that identifies the user. This is the primary user id you should use to reference the user in your app (e.g. for display, storage keys, or API calls). GetUserId() returns the backend-provided user id when available (from user data), or the session’s anonymized user id when the backend does not echo user data (e.g. PII settings), or null when neither is set. SetUserId(id) updates that id in user data and syncs to the API.

You can pass a user data dictionary, or use the overload that takes an id plus variable key-value pairs:

// Dictionary form (optional additionalUserData)
Abxr.SetUserData("user@example.com", new Dictionary<string, string> {
{ "email", "user@domain.com" },
{ "name", "john" }
```cpp
// Get the primary user id (userData.id when present, otherwise session anonymized id)
string userId = Abxr.GetUserId();

// Update the primary user id and sync to the API
Abxr.SetUserId("user@example.com");

Full user data (GetUserData / SetUserData)

For the full set of user data (primary id plus additional fields like email or name), use GetUserData() and SetUserData(). SetUserData() updates the user data and then reauthenticates with the API so the backend has the latest values.

// Get full user data (dictionary; may include id, email, name, etc.)
var userData = Abxr.GetUserData();

// Update user id and/or additional fields, then reauthenticate
Abxr.SetUserData("newUserId", new Abxr.Dict {
{"email", "user@domain.com"},
{"name", "john"}
});

// Params-tuple form: id plus inline key-value pairs
Abxr.SetUserData("user@example.com", ("first_name", "Chad"), ("last_name", "Tester"));

// Id only (no extra pairs)
Abxr.SetUserData("user@example.com");

// No id, only extra pairs
Abxr.SetUserData(null, ("first_name", "Chad"), ("department", "QA"));

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.

// '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();
}
};

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

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:

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();
};

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.

EndSession

End the current session without starting a new one. Flushes all pending data (events, telemetry, logs, storage), closes any running assessment/objective/interaction events, and clears session state. Does not start a new session; call Abxr.StartAuthentication() when you are ready for a fresh session (or use Abxr.StartNewSession() for a full reset including re-auth).

// C# Method Signature
public static void Abxr.EndSession()

// Example usage
Abxr.EndSession();

OnAllModulesCompleted and completion flow

When users finish all assigned modules, you can return them to the home screen with a fresh PIN prompt so the headset is ready for the next user. That flow uses Abxr.OnAllModulesCompleted together with Abxr.EndSession() and Abxr.StartNewSession(). For the full steps and code examples, see Completion flow: return to home with fresh PIN prompt in the Module Targets section.

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
//C# Method Signature
public static void Abxr.StartNewSession()

// 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
//C# Method Signature
public static void Abxr.ReAuthenticate()

// 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

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).

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.

// 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

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:

  1. Remove Mixpanel references from your project
  2. Configure ABXRLib SDK credentials in your project settings
  3. Replace Mixpanel tracking calls with ABXRLib equivalents throughout codebase
// 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

Key Advantages Over Mixpanel

FeatureMixpanelABXRLib 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 PersistenceLimited✅ (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, and AbxrStoragePolicy for compatibility, but the recommended approach is to use the Abxr.* 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:

// 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

Cognitive3D vs ABXRLib

FeatureCognitive3DABXRLib 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).

You can use the built-in keyboard/PIN dialogs as-is, provide your own prefabs via configuration, or take full control by assigning a handler to Abxr.OnInputRequested. The built-in PinPad includes a Guest Access button so users can bypass LMS authentication and access content without LMS tracking when desired.

Option 1: Config prefabs

Assign custom keyboard and PIN pad prefabs in the AbxrLib Configuration asset (Resources → AbxrLib asset, or your project's configuration screen → Authentication Prefabs: Keyboard Prefab and Pin Prefab). When auth needs input, the SDK shows your prefabs using the same flow as the default.

Required components for custom prefabs

To ensure your custom prefab works correctly with the AbxrLib system, include:

  1. KeyboardManager – Required for both keyboards and PIN pads. Handles button interactions, input field management, and submission.
  2. KeyboardKey (on individual key buttons) – Handles key press events for both keyboards and PIN pads.
  3. TMP_InputField – The input field that captures user input (referenced by KeyboardManager).
  4. TextMeshProUGUI with name "DynamicMessage" – Used for prompts (e.g. "Enter your PIN").
  5. Button components on all interactive keys (submit, delete, space, shift for keyboards; number keys for PIN pads, etc.).

Default prefabs in Resources/Prefabs/ (e.g. AbxrKeyboard, AbxrPinPad) can serve as reference.

Nesting considerations

When nesting your custom prefab inside your own UI:

  • FaceCamera: Disable or remove when nesting (see Disabling FaceCamera when nesting above).
  • Canvas: Use appropriate Canvas settings (World Space, Screen Space - Camera, etc.) on your parent structure for your UI design.
  • Component references: References such as KeyboardManager.Instance.inputField work regardless of nesting level; Unity's GetComponent / GetComponentsInChildren traverse the hierarchy.
Example prefab structure
Your Custom UI Container
└── Canvas (your custom canvas settings)
└── Panel/Container (your custom styling)
└── Your Custom Pinpad Prefab (assigned in AbxrLib config)
├── FaceCamera (disabled when nesting)
├── KeyboardManager
├── TMP_InputField
└── [Key buttons with KeyboardKey components]
Disabling FaceCamera when nesting

The default prefabs include a FaceCamera component that positions the UI in front of the camera. When you nest a prefab inside your own UI, disable or remove FaceCamera so your parent controls placement (otherwise world-space positioning may not behave as expected).

In the prefab: Open the prefab in the Unity Editor, select the root GameObject with the FaceCamera component, uncheck it in the Inspector (or remove it), and save.

At runtime: Subscribe to KeyboardHandler.OnKeyboardCreated, find the FaceCamera instance and disable it, and unsubscribe in OnDestroy:

void Start()
{
KeyboardHandler.OnKeyboardCreated += OnKeyboardCreated;
}

void OnDestroy()
{
KeyboardHandler.OnKeyboardCreated -= OnKeyboardCreated;
}

void OnKeyboardCreated()
{
var faceCamera = FindObjectOfType<FaceCamera>();
if (faceCamera != null)
faceCamera.enabled = false;
}
Option 2: Full control (OnInputRequested)

Assign your handler to Abxr.OnInputRequested. Your handler receives four strings: (string type, string prompt, string domain, string error). type is normalized to one of "text" | "pin" | "email" (e.g. backend values like assessmentPin are passed as "pin"). error is empty on first request; on retry after a failed submit (e.g. invalid PIN), it contains a message to show the user. Show your UI using type, prompt, domain, and error. When the user submits, call Abxr.OnInputSubmitted(enteredValue). If there is no outstanding input request, the call is ignored. Set the handler to null in OnDestroy() when your component is no longer responsible for input.

Warning: Your handler must be assigned before auth requests input. With Enable Auto Start Authentication enabled (default), auth can start before your script's Start() runs. Disable Enable Auto Start Authentication in the AbxrLib Configuration asset, assign your handler (e.g. in Start()), then call Abxr.StartAuthentication() so your handler is in place first. Only one handler is active at a time; use assignment (=), not subscribe (+=).

Example (disable auto-start in Configuration first):

void Start()
{
Abxr.OnInputRequested = HandleInputRequested;
Abxr.StartAuthentication();
}

void OnDestroy()
{
Abxr.OnInputRequested = null;
}

void HandleInputRequested(string type, string prompt, string domain, string error)
{
// Show your UI using type, prompt, domain; display error if non-empty (e.g. previous invalid PIN)
// When the user submits, call:
Abxr.OnInputSubmitted(userEnteredValue);
}

For email type, pass only the username to Abxr.OnInputSubmitted; the SDK appends @domain.

QR scanner (custom auth UI)

When using full control (OnInputRequested), you can offer a "Scan QR" option so users can scan a code instead of typing. Use Abxr.IsQRScanForAuthAvailable() to check if QR scanning is available (Meta or Pico); use it to show or hide the Scan QR option. Call Abxr.StartQRScanForAuthInput(Action<string> onResult) to start a scan. When the user scans a code or cancels, the callback is invoked once with the extracted PIN string (e.g. "123456") or null. Close your auth UI and, if value != null, call Abxr.OnInputSubmitted(value). If the user taps Back or Cancel, call Abxr.CancelQRScanForAuthInput() to stop the scan and invoke the callback with null so your handler can close UI without submitting.

On Meta/Quest, Abxr.GetQRScanCameraTexture() returns the camera texture used by the QR reader when available. Assign it to a RawImage in your own UI hierarchy to embed the camera feed and control layout (e.g. parent it under your canvas). The texture may be null until the first scan is started or on Pico (where the platform provides the scanner UI).

Auth UI Follow Camera

Whether the auth keyboard/PIN UI follows the camera or stays in a fixed position is set only in configuration: in the AbxrLib Configuration asset (e.g. Analytics for XR > Configuration), use the Auth UI Follow Camera toggle. At runtime the value is read-only and exposed as Abxr.AuthUIFollowCamera (boolean). When you use config prefabs, the default prefabs respect this setting automatically. If you replace the keyboard (custom prefabs or an OnInputRequested handler), read Abxr.AuthUIFollowCamera to decide whether your UI should follow the camera or remain fixed, so behavior stays consistent with the user's configuration.


Support

Resources

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?

FeatureUnityUnrealWebXR
Basic Event Tracking
Analytics Event Wrappers
Timed Events
Super Meta Data
Logging
Storage
Telemetry
AI Integration
Exit Polls
Module Targets
Authentication
Headset Removal
Session Management
Debug Window🔄 Planned
Debug Mode
ArborXR Device Management🔄 Planned
Mixpanel Compatibility
Cognitive3D Compatibility
Dialog Customization🔄 Planned

Legend: ✅ Supported | 🔄 Planned | ❌ Not Available


Troubleshooting

Problem: PIN/keyboard dialog appears in front of my app initial dialogs and blocks the user

  • Cause: With Headset Login Policy set to anything other than "None" in the ArborXR portal, the SDK starts authentication on launch and shows the PIN dialog before your own UI.
  • Solution: Turn off Enable Auto Start Authentication in Analytics for XR → Configuration (Authentication Control). After the user completes your initial step, call Abxr.StartAuthentication(). See When your app shows initial dialogs before the PIN.

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