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

Flutter · Dart

One line in main. Both stores report back.

Add one package from pub.dev and call AppAmbitSdk.start() once, and your Flutter app reports sessions, device details and crashes on its own. The package carries both native 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.

main.dart · Dart Live
import 'package:flutter/material.dart';
                        import 'package:appambit_sdk_flutter/appambit_sdk_flutter.dart';
                         
                        void main() async {
                          WidgetsFlutterBinding.ensureInitialized();
                         
                          // the whole integration
                          await AppAmbitSdk.start(appKey: '<YOUR-APPKEY>');
                         
                          runApp(const MyApp());
                        }
Sessions, device details and crashes start from that call. appambit_sdk_flutter 1.2.1
One

Package from pub.dev. It carries both native sides.

Two

Apps in AppAmbit, one codebase. iOS and Android.

Zero

Lines of native code you have to write.

3.9

Minimum Dart SDK. Flutter 3.3 and up.

Screen breadcrumbs

Your screens are widgets. Give the SDK the observer.

On a native project the SDK sees every screen the system pushes. In Flutter the routes live in your Dart code, so the native side is blind to them until you hand over an observer. AppAmbitSdk is a NavigatorObserver, so one entry in navigatorObservers is the whole of it, with nothing added inside your screens.

01

Hand it to MaterialApp

Pass navigatorObservers: [AppAmbitSdk()] where you build your app. Once is enough for the life of the app.

02

Name your routes

A breadcrumb carries the route's settings.name, so a page pushed as /cart reads as itself. An unnamed route falls back to its runtime type, which is nobody's idea of a screen name.

03

Pages only, on purpose

Only a PageRoute is recorded, so dialogs, sheets and menus stay out of it and the trail is the screens a person actually moved through.

How the session timeline works
Session trail · one session Recording
ScreenPush /home0.0s
EventProduct openedsku=FL-204
ScreenPush /product2.4s
ScreenPush /cart9.1s
EventCheckout started11.7s
CrashNull check operator used on a null value12.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 codebase, two App Keys

Dart does not care which store it shipped to. AppAmbit does.

An app in AppAmbit belongs to one operating system, so a Flutter 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. AppAmbitSdk.trackEvent, AppAmbitSdk.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.
app_keys.dart · Dart
import 'dart:io' show Platform;
 
const iosKey = '<IOS-APPKEY>';
const androidKey = '<ANDROID-APPKEY>';
 
await AppAmbitSdk.start(
  appKey: Platform.isIOS ? iosKey : androidKey,
);
Two keys, one call site. dart:io
Create your two apps

One team, one App Key per store, and both of them on the same free tier.

The whole API

Six things to write, and you have seen all of it.

There is no client to configure, no pipeline to describe and no schema to declare. Five of these are static calls on the same class, awaited like anything else in Dart, and the sixth is an observer you hand to MaterialApp once.

AppAmbitSdk.start(appKey: key)

Turn it on

One call in main, after the binding is ready. Sessions, device details and crashes start from that line.

Session Timeline

navigatorObservers: [AppAmbitSdk()]

Hand over your routes

The SDK is a NavigatorObserver. Give one to your MaterialApp and every push, pop and replace becomes a breadcrumb, with nothing to instrument inside your screens.

Breadcrumbs

AppAmbitSdk.trackEvent(title, props)

Record something

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

Event Tracking

AppAmbitSdk.logError(exception:, stackTrace:)

Report a caught error

The exception you already handled, with its stack trace and an optional properties map, sent as a log rather than a crash.

Crash and Error Monitoring

AppAmbitSdk.logError(message:)

Report without an exception

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

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

Sessions are automatic. If you would rather draw their boundaries yourself, call AppAmbitSdk.enableManualSession() before starting the SDK and then startSession() and endSession() where they belong.

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 into main 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 before they left.

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. Register the observer and your routes write it for you.

Breadcrumbs

Remote config

Typed values you change from the dashboard, with no rebuild and no wait behind either store.

Remote config

App Database

A managed SQL database for the app, with no server to run and no connection string bundled into your build.

App Database

Cloud Code

Node.js functions you deploy inside AppAmbit, for the logic that has no business living in the client.

Cloud Code

Content management

Query a content type straight into your own Dart model, so copy and screens change without a release.

CMS guide

Push notifications

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

Push notifications

Build delivery

Hand the ipa and the 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 Flutter release is two artifacts, and both can land here. Upload the ipa and the apk from the CI 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 both targets 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, and none of them are native.

Create your app in the dashboard to get an App Key, then add one dependency and one call. The last step is the only place the two platforms differ, and only in which device you point the run at.

01

Add the package

One dependency, from pub.dev. Version 1.2.1 is the current release. The iOS and Android sides ship inside it, so this is the only install.

# the current release
                            flutter pub add appambit_sdk_flutter
// or pin it yourself, then flutter pub get
                            dependencies:
                              flutter:
                                sdk: flutter
                              appambit_sdk_flutter: ^1.2.1
Flutter resolves the native dependency for both platforms. Dart 3.9+
02

Start it in main

After ensureInitialized() and before runApp, so the SDK is up before the first frame and the first session covers the whole launch.

main.dart · Dart
import 'package:appambit_sdk_flutter/appambit_sdk_flutter.dart';
                         
                        void main() async {
                          WidgetsFlutterBinding.ensureInitialized();
                          await AppAmbitSdk.start(appKey: '<YOUR-APPKEY>');
                          runApp(const MyApp());
                        }
The App Key is on the app's Info page in the dashboard. One call
03

Run it on a device

A hot reload will not pick up a new native dependency, so this first one has to be a full run. On iOS the Flutter tool installs the pod for you; on Android Gradle resolves it.

Terminal · iOS Terminal · Android
# pods are installed by the tool on the first run
                            flutter run -d ios
# gradle resolves the native side on the first run
                            flutter run -d android
The session lands while the app is still on screen. The session lands while the app is still on screen. Done

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 a Firebase project and its two config files, AppAmbit keeps the device tokens, and you send from the dashboard or from a Cloud Code function.

Add appambit_sdk_push_notifications next to the core package and start it after the SDK. On iOS the pods resolve on their own; Android wants the Google Services plugin and Firebase Messaging in Gradle.
Two listeners, and a handler for the killed app. setForegroundListener and setOpenedListener work on both platforms. On Android, Android.setBackgroundHandler runs a top-level function in its own isolate; on iOS that work belongs in the Notification Service Extension.
The payload is typed. PushNotificationData carries title, body, imageUrl and your own data map, plus the android and ios blocks for the fields only one platform has.
How push notifications work
main.dart · push
await AppAmbitSdk.start(appKey: '<YOUR-APPKEY>');
PushNotificationsSdk.start();
 
// ask when the moment makes sense, not at launch
PushNotificationsSdk.requestNotificationPermission();
 
// fires when the user taps one, in any app state
PushNotificationsSdk.setOpenedListener((push) {
  final screen = push.data?['screen'];
  if (screen != null) openScreen(screen);
});
Both calls go after AppAmbitSdk.start, 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?
Two. An app in AppAmbit belongs to one operating system, so a Flutter 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 AppAmbitSdk.start, and the rest of your Dart code never has to know which one it got.
Do I have to write any native code?
No. The package ships the iOS and Android sides with it. You add one dependency, call AppAmbitSdk.start in main, and build as usual: the Flutter tool installs the CocoaPods dependency on iOS and Gradle picks the Android one up on its own.
What are the minimum versions?
Flutter 3.3.0 and Dart 3.9.0 for the package itself. On top of that you keep whatever iOS and Android minimums your own Flutter app already declares.
Does it work on Flutter web or desktop?
Not today. The package declares Android and iOS, which are the two platforms it ships native code for. A web or desktop build will not find an implementation.
How do I report an error I already caught?
Call AppAmbitSdk.logError with the exception and its stack trace, or with a message when there is no exception object to hand. Both take an optional properties map, so you can attach the ids you will want when you read it back.
Are the database and the CMS part of the same package?
Yes. AppAmbitDb, CloudCode and AppAmbitCms come from the same import as AppAmbitSdk and go out on the App Key you already started the SDK with. There is no second package to add and no second set of credentials to ship.
Can I read remote values without shipping a release?
Yes. Call AppAmbitSdk.enableConfig before you start the SDK, then read values with getString, getLong, getDouble and getBoolean. The values come from your dashboard, so changing one does not need a new build.

Building for the other platforms too? AppAmbit has an SDK for iOS, Android, React Native, .NET MAUI, .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.

Ready when you are

Add the package. Watch the first session land.

Create a free account, paste your App Key into main, and run the app. The first session shows up while it is still on screen, and the next crash comes back with the device and the session it happened in. Flutter 3.3 and up, no credit card.

One package, and both stores report.

Start free