A user action represents a significant operation within your app—it groups the requests, navigations, and errors that result from a single user interaction into one event. For a full conceptual overview of how user actions start, end, and what data they capture, see User actions. The sections below cover only .NET MAUI-specific instrumentation details.
User actions triggered by the API let you track custom workflows that the agent cannot instrument automatically, such as multi-step business processes, background tasks, or interactions that span multiple screens.
Use Agent.Instance.CreateUserAction(UserActionConfiguration) to start a user action triggered by the API. Pass a UserActionConfiguration with a custom name that describes the workflow you are tracking. Call Complete() when the workflow finishes.
CreateUserAction always returns a user action, and invalid usage (for example, providing an empty custom name) is handled silently.
IUserAction userAction = Agent.Instance.CreateUserAction(new UserActionConfiguration("Checkout Process"));// ... perform the workflow ...userAction.Complete();
By default, you must call Complete() explicitly. If your workflow triggers web requests and you want the user action to close automatically once all in-flight requests finish, set completeAutomatically: true.
IUserAction userAction = Agent.Instance.CreateUserAction(new UserActionConfiguration("Checkout Process", completeAutomatically: true));// The user action closes on its own once pending requests finish.// You can still call Complete() to close it earlier.
You can also change this behavior at any point during the user action's lifetime with SetCompleteAutomatically(bool).
Use AddEventProperty to attach custom data to the user action. Property keys must be prefixed with event_properties.. Properties added after Complete() is called are silently ignored.
For property naming rules and limits, see Event and session properties.
IUserAction userAction = Agent.Instance.CreateUserAction(new UserActionConfiguration("Checkout Process"));userAction.AddEventProperty("event_properties.payment_method", "credit_card");userAction.AddEventProperty("event_properties.cart_value", 149.99);userAction.AddEventProperty("event_properties.item_count", 3);// ... perform the workflow ...userAction.Complete();
The following example tracks a checkout workflow as a single user action that spans multiple methods. The action is started in the button handler so that its start time matches the user's selection, kept as a field on the ViewModel while the payment is processed, and closed—with outcome properties attached—in both the success and error paths.
CheckoutViewModel.cs
public class CheckoutViewModel : ObservableObject{private readonly IPaymentRepository _paymentRepository;private IUserAction? _checkoutAction;public CheckoutViewModel(IPaymentRepository paymentRepository){_paymentRepository = paymentRepository;}// Called from the UI layer when the user taps the "Checkout" button.// CreateUserAction() is invoked here so the action start time accurately// reflects the button tap.public async Task OnCheckoutButtonClickedAsync(Cart cart){_checkoutAction = Agent.Instance.CreateUserAction(new UserActionConfiguration("Checkout Process"));_checkoutAction.AddEventProperty("event_properties.cart_id", cart.Id);_checkoutAction.AddEventProperty("event_properties.item_count", cart.Items.Count);_checkoutAction.AddEventProperty("event_properties.cart_total", cart.Total);_checkoutAction.AddEventProperty("event_properties.currency", cart.Currency);await ProcessPaymentAsync(cart);}private async Task ProcessPaymentAsync(Cart cart){try{PaymentResult result = await _paymentRepository.ProcessPaymentAsync(cart);CompleteCheckout(result.OrderId);}catch (Exception ex){CancelCheckout(ex.Message ?? "unknown_error");}}private void CompleteCheckout(string orderId){_checkoutAction?.AddEventProperty("event_properties.order_id", orderId);_checkoutAction?.AddEventProperty("event_properties.checkout_successful", true);_checkoutAction?.Complete();_checkoutAction = null;}private void CancelCheckout(string reason){_checkoutAction?.AddEventProperty("event_properties.checkout_successful", false);_checkoutAction?.AddEventProperty("event_properties.cancellation_reason", reason);_checkoutAction?.Complete();_checkoutAction = null;}}