●  New: build your backend and app together with AI. Point Claude or Cursor at AppAmbit over MCP.

On mobile?

Email yourself the setup link so you can finish when you're at your computer.

.NET MAUI · C#

One line in MauiProgram. Every head reports back.

Add one NuGet reference and chain UseAppAmbit onto your builder, and your MAUI app reports sessions, device details and crashes on its own. The package carries the platform sides with it, so there is no Swift or Kotlin for you to write.

No credit card required. Free tier available. The same SDK also gives you a database, cloud functions and remote config.

MauiProgram.cs · C# Live
using AppAmbit;
 
public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
 
    // the whole integration
    builder
        .UseMauiApp<App>()
        .UseAppAmbit("<YOUR-APPKEY>");
 
    return builder.Build();
}
Sessions, device details and crashes start from that call. com.AppAmbit.Maui 4.2.0
One

NuGet reference. It carries every platform side.

Four

Heads from one project. iOS, Android, macOS, Windows.

Zero

Lines of platform code you have to write.

4.2

Current release, resolved from NuGet.

Session Timeline

You write the pages. The timeline writes itself.

The session timeline records what a person did on the way to a crash: the pages they moved through and the events you sent, in order, with the crash at the end. It comes with the package, so there is nothing to instrument inside your views.

01

It is on from the first line

The session timeline starts with the SDK. There is no separate call to make and nothing to register inside your pages.

02

Your own steps join it

Anything you send with Analytics.TrackEvent lands on the same timeline, so a business step reads next to the navigation that led to it.

03

It travels with the crash

When a crash arrives, the timeline arrives with it. You open the report and the last six things that happened are already there.

How the session timeline works
Session timeline · one session Recording
ScreenHomePage0.0s
EventProduct openedsku=NET-204
ScreenProductPage2.4s
ScreenCartPage9.1s
EventCheckout started11.7s
CrashNullReferenceException: Object reference not set12.0s

Six breadcrumbs, and the last one is the crash. This is what arrives attached to the report.

See a session timeline

Every crash lands inside the session that led to it, with the run-up already attached.

One project, two App Keys

C# does not care which store it shipped to. AppAmbit does.

An app in AppAmbit belongs to one operating system, so a MAUI project that reaches both stores gets an iOS app and an Android app. Pick between their keys where you start the SDK and the rest of your code never has to know which one it got.

Two apps in the dashboard, each with its own App Key on its Info page and its own crash list. An Android crash never lands in the iOS app.
The same calls either way. Analytics.TrackEvent, Crashes.LogError and the rest are identical on both sides of the switch.
One place to read them. Both apps sit in the same team, so the crash you are chasing is two clicks from the one you just read.
MauiProgram.cs · C#
const string iosKey = "<IOS-APPKEY>";
const string androidKey = "<ANDROID-APPKEY>";
 
#if IOS
    builder.UseAppAmbit(iosKey);
#else
    builder.UseAppAmbit(androidKey);
#endif
Two keys, one call site. Conditional compilation
Create your apps

One team, one App Key per operating system, and every head on the same free tier.

The whole API

Six calls, and you have seen all of it.

There is no client to configure, no pipeline to describe and no schema to declare. Every one of these is a static call on a class you already have in scope, awaited like anything else in C#.

builder.UseAppAmbit(appKey)

Turn it on

One chained call in MauiProgram, before the builder is built. Sessions, device details and crashes start from that line.

Session Timeline

Analytics.TrackEvent(title, data)

Record something

A name and a dictionary of strings. The dashboard groups by the name and keeps the properties on each occurrence.

Event Tracking

Crashes.LogError(exception, properties)

Report a caught error

The exception you already handled, sent as a log rather than a crash. The file and the line come from the compiler, so you do not pass them.

Crash and Error Monitoring

Crashes.LogError(message)

Report without an exception

The same list, for the times you have a sentence and no exception object. Properties work here too.

Analytics.EnableManualSession()

Draw the sessions yourself

Sessions start and end on their own. Turn that off and call StartSession and EndSession where they belong in your own flow.

Crashes.GenerateTestCrash()

Prove the pipeline

Force one on purpose and watch it arrive. The fastest way to know the App Key and the build are wired up.

Nothing waits on the network. Every call writes to a local SQLite queue first and the queue is sent in batches when a connection is there, so a flight or a tunnel does not cost you a session.

The context comes with it. A crash arrives inside the session it happened in, next to the breadcrumbs and the events that came before it, so you read the run-up rather than a bare stack.

Get an App Key

That is the whole surface. The key that makes those calls report takes a minute to create.

Everything else in the account

The rest of AppAmbit is already pointed at this app.

All of it runs on the App Key you pasted in and the team the app belongs to. Nothing on this row is another vendor to pick, another SDK to add or another invoice to get approved.

App Analytics

Who opened the app, on which OS version and build, and how long they stayed.

App Analytics

Event Tracking

The events you name yourself, with their properties kept on every occurrence and grouped in the dashboard.

Event Tracking

Session Timeline

Every crash arrives inside the session it happened in, next to the events and logs that came before it.

Session Timeline

Breadcrumbs

The trail that led to the crash, recorded as you move through pages, so you read a path instead of guessing one.

Breadcrumbs

Remote config

Flip a flag or change a value and your app picks it up, with no rebuild and no wait behind a store.

Remote config

App Database

Real SQL from C#, with no server to run and no connection string compiled into the app.

App Database

Cloud Code

Call a Node.js function you deployed inside AppAmbit, and get the response back typed or dynamic.

Cloud Code

Content management

Read published content types and entries into your own model class, so copy can change without a release.

CMS guide

Push notifications

One more package beside the core one, your own credentials, and the tokens already tied to your App Key.

Push notifications

Build delivery

Hand an ipa or an apk to your testers over a link, and see who is running which one.

Build delivery

AI Agent over MCP

Point Claude or Cursor at AppAmbit over MCP and let it read your crashes and sessions, or set the backend up for you.

AI Agent

AI App Builder

Ask Claude or Cursor for a feature and let it provision the backend that feature needs, on this same account.

AI App Builder
Open an account

Everything on this row is included, on the same App Key and the same free tier.

Build delivery

The build your tester installs is the build you read crashes from.

A MAUI release is more than one artifact, and the mobile ones can land here. Upload the ipa and the apk from the pipeline you already run, hand testers a link, and the crashes that come back are already tied to the build they came from. The build guides have the pipeline steps.

.ipa .apk Build delivery

GitHub Actions

Build every head in one workflow and let the signed webhook hand the ipa and the apk straight to AppAmbit.

Bitbucket Pipelines

Wire a pipeline step to publish each build, with the branch, commit and author carried along.

Azure DevOps

Connect an Azure pipeline and every green build shows up ready to send to your testers.

Distribute your first build

Connect the repository, and testers install from a link instead of waiting on a store.

Setup

Three steps, none of them are native.

Create your app in the dashboard to get an App Key, then add one reference and one chained call. These three steps are the same for every head your project builds for, because the SDK call does not change with the target.

01

Add the package

One reference, from NuGet. Version 4.2.0 is the current release. It pulls in com.AppAmbit.Sdk, which is where the work actually happens.

# the current release
dotnet add package com.AppAmbit.Maui
<!-- or pin it yourself, then dotnet restore -->
<ItemGroup>
  <PackageReference Include="com.AppAmbit.Maui"
                    Version="4.2.0" />
</ItemGroup>
One reference. NuGet resolves the platform assemblies. .NET 10
02

Chain it onto the builder

In CreateMauiApp, after UseMauiApp and before Build, so the SDK is up before the first page and the first session covers the whole launch.

MauiProgram.cs · C#
using AppAmbit;
 
    builder
        .UseMauiApp<App>()
        .UseAppAmbit("<YOUR-APPKEY>");
The App Key is on the app's Info page in the dashboard. One call
03

Run it

Build and run the head you are working on. The first run has to be a full build, since a hot reload will not pick up a new native dependency.

Terminal · first run
# swap the framework for the head you want; nothing else changes
dotnet build -t:Run -f net10.0-android
The session lands while the app is still on screen. First run

Prefer the long version? The getting started guide covers the same three steps with the dashboard screens next to them.

Create your App Key

Step one is a free account. The other two take about five minutes.

Push notifications

One more package, not another vendor.

Push runs on the same App Key and the same install. You bring the APNs and Firebase credentials from your own developer accounts, AppAmbit keeps the device tokens, and you send from the dashboard or from a Cloud Code function.

Add com.AppAmbit.PushNotifications next to the core package and start it after the SDK. It covers the Android and iOS heads, so the desktop heads keep building and simply have no push.
Two listeners, and a handler for the killed app. SetForegroundListener and SetOpenedListener take a plain Action, and registering again replaces the previous one rather than stacking a second.
The payload is a record. PushNotificationData carries title, body, imageUrl and your own data, plus the AndroidPushData and IosPushData blocks for the fields only one platform has.
How push notifications work
MauiProgram.cs · push
PushNotifications.Start();
 
// ask when the moment makes sense, not at launch
PushNotifications.RequestNotificationPermission();
 
// fires when the user taps one, in any app state
PushNotifications.SetOpenedListener(push =>
{
    if (push.Data?.TryGetValue("screen", out var s) == true)
        GoTo(s);
});
Both calls go after the SDK starts, which registers the device. Android and iOS
Set up push

Your own credentials, the tokens already tied to your App Key, and no second vendor to sign with.

Questions

Answered straight.

Do I need one App Key or two for a MAUI app?
Two. An app in AppAmbit belongs to one operating system, so a MAUI project that ships to both stores has an iOS app and an Android app, each with its own App Key and its own crash list. Pick between them where you call UseAppAmbit, and the rest of your C# never has to know which one it got.
Do I have to write any platform code?
No. The package carries the platform sides with it. You add one reference, start the SDK once, and build as usual.
What does it cost me at runtime?
A background queue and a small SQLite file. Everything is batched, retried and sent when the network is there, so a plane ride does not lose a session.
Can I use it with my own logging?
Yes. Crashes.LogError is additive, so keep whatever logger you already have and send AppAmbit the errors you want to read next to your crashes.
Does it work on the macOS and Windows heads?
The package ships assemblies for net10.0, android, ios, maccatalyst and windows, so every head of a MAUI project builds against it. Push notifications are the one part that only covers the mobile heads.
Where do the file and the line in a log come from?
The compiler. Crashes.LogError takes CallerFilePath and CallerLineNumber, so the location is filled in at the call site and you never pass it yourself.

Building for the other platforms too? AppAmbit has an SDK for iOS, Android, React Native, Flutter, .NET and Avalonia. Each one takes its own App Key and reports into the same dashboard, on the same team and the same bill.

Try it on your own app

The free tier is enough to point the SDK at a real build and read your own sessions.

Add the package. Watch the first session land.

One reference, one chained call, and the first session shows up while the app is still open. The database, the functions and the flags are already behind the same key.

No credit card required. Free tier available.