
This is the official documentation for the Amplitude Analytics Flutter SDK. The Flutter SDK lets you send events from your Flutter application to Amplitude.

## Compatibility

Amplitude Flutter v4 bumps the Kotlin version to v1.9.22 to support the latest Gradle.

The following matrix lists the minimum support for the Amplitude Flutter SDK version.

| Amplitude Flutter | Dart  | Flutter | Gradle | Android Gradle Plugin | Kotlin Gradle Plugin |
| ----------------- | ----- | ------- | ------ | --------------------- | -------------------- |
| >= 4.0.0          | >=3.3 | >=3.7   | 8.2    | 8.2.2                 | 1.9.22               |

## Install the SDK

Run the following command to get the latest version of `amplitude_flutter`, add it to your `pubspec.yaml`, then retrieve dependencies:

```bash
flutter pub add amplitude_flutter
```

### iOS installation

Add `platform :ios, '13.0'` to your Podfile. Run `pod install` in the ios directory of your Flutter project to update the CocoaPods dependencies.

To enable Bitcode, follow Flutter's [documentation](https://github.com/flutter/flutter/wiki/Creating-an-iOS-Bitcode-enabled-app).

### macOS installation

Add `platform :osx, '10.15'` to your Podfile. Run `pod install` in the macos directory of your Flutter project to update the CocoaPods dependencies.
Ensure your app has the `com.apple.security.network.client` entitlement to be able to send requests. Manually edit the `macos/Runner/Release.entitlements` and `macos/Runner/DebugProfile.entitlements` files to include:

```xml
	<key>com.apple.security.network.client</key>
	<true/>
```

Refer to [Flutter's documentation](https://docs.flutter.dev/platform-integration/macos/building#setting-up-entitlements) for more information.

### Web installation (optional)

The Flutter SDK uses Dart's JavaScript interoperability to enable [Browser SDK 2](/docs/sdks/analytics/browser/browser-sdk-2) for Flutter Web. This requires that you make the SDK available within the global JavaScript scope. Add the following Browser SDK 2 snippet to `web/index.html` in your Flutter project:

```html
<script type="text/javascript">
  !(function () {
    "use strict";
    !(function (e, t) {
      var r = e.amplitude || { _q: [], _iq: {} };
      if (r.invoked)
        e.console &&
          console.error &&
          console.error("Amplitude snippet has been loaded.");
      else {
        var n = function (e, t) {
            e.prototype[t] = function () {
              return (
                this._q.push({
                  name: t,
                  args: Array.prototype.slice.call(arguments, 0),
                }),
                this
              );
            };
          },
          s = function (e, t, r) {
            return function (n) {
              e._q.push({
                name: t,
                args: Array.prototype.slice.call(r, 0),
                resolve: n,
              });
            };
          },
          o = function (e, t, r) {
            e._q.push({ name: t, args: Array.prototype.slice.call(r, 0) });
          },
          i = function (e, t, r) {
            e[t] = function () {
              if (r)
                return {
                  promise: new Promise(
                    s(e, t, Array.prototype.slice.call(arguments)),
                  ),
                };
              o(e, t, Array.prototype.slice.call(arguments));
            };
          },
          a = function (e) {
            for (var t = 0; t < g.length; t++) i(e, g[t], !1);
            for (var r = 0; r < m.length; r++) i(e, m[r], !0);
          };
        r.invoked = !0;
        var c = t.createElement("script");
        ((c.type = "text/javascript"),
          (c.integrity =
            "sha384-R0H1kXlk6r2aEQMtwVcPolpk0NAuIqM/8NlxAv24Gr3/PBJPl+9elu0bc3o/FDjR"),
          (c.crossOrigin = "anonymous"),
          (c.async = !0),
          (c.src =
            "https://cdn.amplitude.com/libs/analytics-browser-2.11.10-min.js.gz"),
          (c.onload = function () {
            e.amplitude.runQueuedFunctions ||
              console.log("[Amplitude] Error: could not load SDK");
          }));
        var l = t.getElementsByTagName("script")[0];
        l.parentNode.insertBefore(c, l);
        for (
          var u = function () {
              return ((this._q = []), this);
            },
            p = [
              "add",
              "append",
              "clearAll",
              "prepend",
              "set",
              "setOnce",
              "unset",
              "preInsert",
              "postInsert",
              "remove",
              "getUserProperties",
            ],
            d = 0;
          d < p.length;
          d++
        )
          n(u, p[d]);
        r.Identify = u;
        for (
          var f = function () {
              return ((this._q = []), this);
            },
            v = [
              "getEventProperties",
              "setProductId",
              "setQuantity",
              "setPrice",
              "setRevenue",
              "setRevenueType",
              "setEventProperties",
            ],
            y = 0;
          y < v.length;
          y++
        )
          n(f, v[y]);
        r.Revenue = f;
        var g = [
            "getDeviceId",
            "setDeviceId",
            "getSessionId",
            "setSessionId",
            "getUserId",
            "setUserId",
            "setOptOut",
            "setTransport",
            "reset",
            "extendSession",
          ],
          m = [
            "init",
            "add",
            "remove",
            "track",
            "logEvent",
            "identify",
            "groupIdentify",
            "setGroup",
            "revenue",
            "flush",
          ];
        (a(r),
          (r.createInstance = function (e) {
            return ((r._iq[e] = { _q: [] }), a(r._iq[e]), r._iq[e]);
          }),
          (e.amplitude = r));
      }
    })(window, document);
  })();
</script>
```

## Initialize the SDK

{% callout type="note" heading="Sending events" %}
This SDK uses the [HTTP V2](/docs/apis/analytics/http-v2) API and follows the same constraints for events. Make sure all events logged in the SDK contain at least one of `deviceId` (included by default) or `userId`, and follow the HTTP API's constraints on each of those fields.

To prevent instrumentation issues, device IDs and user IDs must be strings with a length of 5 characters or more. If an event contains a device ID or user ID that's too short, Amplitude removes the ID value from the event. If the event doesn't have a `userId` or `deviceId` value, Amplitude may reject the upload with a 400 status. Override the default minimum length of 5 characters by setting the `minIdLength` config option.
{% /callout %}

Before you instrument your application, initialize the SDK with your Amplitude project's API key.

```dart
import 'package:amplitude_flutter/amplitude.dart';
import 'package:amplitude_flutter/configuration.dart';
import 'package:amplitude_flutter/events/base_event.dart';

class YourClass {
  Future<void> exampleForAmplitude() async {
    // Create and initialize the instance
    final Amplitude amplitude = Amplitude(Configuration(
        apiKey: 'YOUR-API-KEY',
    ));

    // Wait until the SDK is initialized
    await amplitude.isBuilt;

    // Track an event
    amplitude.track(BaseEvent(
        eventType: 'BUTTON_CLICKED',
        eventProperties: {'Hover Time': '100ms'},
    ));

    // Send events to the server
    amplitude.flush()
  }
}
```

## Configure the SDK

| Name                           | Description                                                                                                                                                                                                                                                                                                                     | Default Value                          |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| `apiKey`                       | `String`. The apiKey of your project.                                                                                                                                                                                                                                                                                           | `null`                                 |
| `flushQueueSize`               | `int`. The SDK attempts to upload when the unsent event count exceeds the event upload threshold or reaches the `flushIntervalMillis` interval.                                                                                                                                                                                             | `30`                                   |
| `flushIntervalMillis`          | `int`. The amount of time the SDK waits before it attempts to upload unsent events to the server or before it reaches the `flushQueueSize` threshold. The value is in milliseconds.                                                                                                                                                                       | `30000`                                |
| `instanceName`                 | `String`. The name of the instance. Instances with the same name share storage and identity. For isolated storage and identity, use a unique `instanceName` for each instance.                                                                                                                                                  | `$default_instance`                    |
| `optOut`                       | `bool`. Opt the user out of tracking.                                                                                                                                                                                                                                                                                           | `false`                                |
| `logLevel`                     | `LogLevel` The log level. `LogLevel.off`, `LogLevel.error`, `LogLevel.warn`, `LogLevel.log`, `LogLevel.debug`                                                                                                                                                                                                                   | `LogLevel.warn`                        |
| `minIdLength`                  | `int`. The minimum length for user id or device id.                                                                                                                                                                                                                                                                             | `5`                                    |
| `partnerId`                    | `int`. The partner id for partner integration.                                                                                                                                                                                                                                                                                  | `null`                                 |
| `flushMaxRetries`              | `int`. Maximum retry times.                                                                                                                                                                                                                                                                                                     | `5`                                    |
| `useBatch`                     | `bool`. Whether to use batch API.                                                                                                                                                                                                                                                                                               | `false`                                |
| `serverZone`                   | `ServerZone`. `ServerZone.us` or `ServerZone.eu`. The server zone Amplitude sends data to. Amplitude adjusts the server URL based on this config.                                                                                                                                                                                                           | `ServerZone.us`                        |
| `serverUrl`                    | `String`. The server URL the SDK uploads events to.                                                                                                                                                                                                                                                                                      | `https://api2.amplitude.com/2/httpapi` |
| `minTimeBetweenSessionsMillis` | `int`. The amount of time for session timeout. The value is in milliseconds. Defaults to 300,000 (5 minutes) for iOS/Android and 1,800,000 (30 minutes) for Web. Overriding this value changes the session timeout for all platforms. This maps to `minTimeBetweenSessionsMillis` for iOS/Android and `sessionTimeout` for Web. | `300000`                               |
| `trackingOptions`              | `TrackingOptions`. Options to control the values tracked in SDK.                                                                                                                                                                                                                                                                | `enable`                               |
| `autocapture`                  | `Autocapture`. Configures autocapture for sessions, app lifecycles, deep links, page views, and marketing attribution. Use `AutocaptureDisabled()`, `AutocaptureEnabled()`, or `AutocaptureOptions()` for granular control. Refer to [Autocapture](#autocapture).                                                                   | Derived from `defaultTracking` when not set explicitly |

### Configuration for Android and iOS

| Name                          | Description                                                                                                                                                                                                                                                                                                                  | Default Value                                           |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| ~`defaultTracking`~ (Deprecated. Use [`autocapture`](#autocapture) instead.) | `DefaultTrackingOptions`. Options to control default event tracking. When you don't set `autocapture` explicitly, the SDK derives it from `defaultTracking`.                                                                                               | `DefaultTrackingOptions(sessions: true)`                |
| `enableCoppaControl`          | `bool`. Whether to enable COPPA control for tracking options.                                                                                                                                                                                                                                                                | `false`                                                 |
| `flushEventsOnClose`          | `bool`. Flush unsent events on app close.                                                                                                                                                                                                                                                                                    | `true`                                                  |
| `identifyBatchIntervalMillis` | `int`. The amount of time the SDK waits before it batches intercepted identify events. The value is in milliseconds.                                                                                                                                                                                                       | `30000`                                                 |
| `migrateLegacyData`           | `bool`. Whether to migrate maintenance Android SDK and maintenance iOS SDK data (events, user/device ID). Learn more at the configuration section of the underlying [Kotlin SDK](/docs/sdks/analytics/android/android-kotlin-sdk/#configuration) and [Swift SDK](/docs/sdks/analytics/ios/ios-swift-sdk/#configure-the-sdk). | `true`                                                  |

### Configuration for web and Android

| Name       | Description                                                                                                 | Default Value |
| ---------- | ----------------------------------------------------------------------------------------------------------- | ------------- |
| `deviceId` | `String`. The device ID to use for this device. If you don't provide a `deviceId`, Amplitude generates one. | `null`        |

### Configuration for Android

| Name                          | Description                                                                                                                                                          | Default Value |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `locationListening`           | `bool`. Whether to enable Android location service. Learn more [here](/docs/sdks/analytics/android/android-kotlin-sdk/#location-tracking).                           | `true`        |
| `useAdvertisingIdForDeviceId` | `bool`. Whether to use advertising id as device id. Check [here](/docs/sdks/analytics/android/android-kotlin-sdk/#advertiser-id) for required module and permission. | `false`       |
| `useAppSetIdForDeviceId`      | `bool`. Whether to use app set id as device id. Check [here](/docs/sdks/analytics/android/android-kotlin-sdk/#app-set-id) for required module and permission.        | `false`       |

### Configuration for web

- **`appVersion`**
  - **Description**: `String`. Sets an app version for events tracked. This can be the version of your application. For example: "1.0.0".
  - **Default Value**: `null`
- **`cookieOptions.domain`**
  - **Description**: `String`. Sets the domain property of cookies created.
  - **Default Value**: `null`
- **`cookieOptions.expiration`**
  - **Description**: `int`. Sets expiration of cookies created in days.
  - **Default Value**: 365 days
- **`cookieOptions.sameSite`**
  - **Description**: `String`. Sets `SameSite` property of cookies created.
  - **Default Value**: `null`
- **`cookieOptions.secure`**
  - **Description**: `bool`. Sets `Secure` property of cookies created.
  - **Default Value**: `null`
- **`cookieOptions.upgrade`**
  - **Description**: `bool`. Sets upgrading from cookies created by [maintenance Browser SDK](/docs/sdks/analytics/browser/javascript-sdk). If `true`, new Browser SDK deletes cookies created by maintenance Browser SDK. If `false`, Browser SDK keeps cookies created by maintenance Browser SDK.
  - **Default Value**: `null`
- **`identityStorage`**
  - **Description**: `String`. Sets storage API for user identity. Options include cookie for `document.cookie`, `localStorage` for `localStorage`, or none to opt-out of persisting user identity.
  - **Default Value**: `cookie`
- **`userId`**
  - **Description**: `String`. Sets an identifier for the tracked user. Must have a minimum length of 5 characters unless overridden with the minIdLength option.
  - **Default Value**: `null`
- **`transport`**
  - **Description**: `String`. Sets request API to use by name. Options include `fetch` for `fetch`, `xhr` for `XMLHTTPRequest`, or `beacon` for `navigator.sendBeacon`.
  - **Default Value**: `fetch`
- **`fetchRemoteConfig`**
  - **Description**: `bool`. Whether the SDK fetches remote configuration. Review [Browser SDK 2](/docs/sdks/analytics/browser/browser-sdk-2#remote-configuration) for more information. The default depends on the Browser SDK version used. For Browser SDK 2.16.1+, the default is `true`.
  - **Default Value**: `false` (for Browser SDK = 2.16.1)

### Configure batching behavior

To support high-performance environments, the SDK sends events in batches. The `track` method queues every event in memory, and the SDK flushes events in batches in the background. Customize batch behavior with `flushQueueSize` and `flushIntervalMillis`. By default, the `serverUrl` is `https://api2.amplitude.com/2/httpapi`.

If you need to send large batches of data at once, set `useBatch` to `true`. This sets `setServerUrl` to the batch event upload API `https://api2.amplitude.com/batch`. Both the regular mode and the batch mode use the same events upload threshold and flush time intervals.

```dart
final Amplitude analytics = Amplitude(Configuration(
    apiKey: 'YOUR-API-KEY',
    flushIntervalMillis: 50000,
    flushQueueSize: 20,
));
```

### EU data residency

Configure the server zone when you initialize the client to send data to Amplitude's EU servers. The SDK sends data based on the server zone if you set it.

{% callout type="note" heading="" %}
For EU data residency, the project must be set up inside Amplitude EU. You must initialize the SDK with the API key from Amplitude EU.
{% /callout %}

```dart
final Amplitude analytics = Amplitude(Configuration(
    apiKey: 'YOUR-API-KEY',
    serverZone: ServerZone.eu,
));
```

## Track

Events represent how users interact with your application. For example, "Song Played" can be an action you want to track.

```dart
amplitude.track(BaseEvent('Song Played'));
```

You can also optionally include event properties.

```dart
amplitude.track(BaseEvent('Song Played', eventProperties: {'title': 'Happy Birthday'}));
```

Refer to the [BaseEvent](https://github.com/amplitude/Amplitude-Flutter/blob/beta/lib/events/base_event.dart) interface for all available fields.

## Identify

Use Identify to set the user properties of a particular user without sending any event. The SDK supports the `set`, `setOnce`, `unset`, `add`, `append`, `prepend`, `preInsert`, `postInsert`, `remove`, and `clearAll` operations on individual user properties. Declare the operations with the provided Identify interface. You can chain multiple operations in a single Identify object, then pass the Identify object to the Amplitude client to send to the server.

{% callout type="note" heading="" %}
If you send the Identify call after the event, the results of operations appear immediately in the dashboard user's profile area, but they don't appear in chart results until the SDK sends another event after the Identify call. As a result, the Identify call only affects future events. For more information, refer to [User Properties and Events](/docs/data/user-properties-and-events).
{% /callout %}

You can handle a user's identity using the identify methods. Proper use of these methods connects events to the correct user as the user moves across devices, browsers, and other platforms. Send an identify call containing those user property operations to the Amplitude server to tie a user's events to specific user properties.

```dart
final Identify identify = Identify()
    ..set('color', 'green')
amplitude.identify(identify)
```

### Clear all user properties

Use `clearAll` to remove all user properties from a user. Use `clearAll` with care because the operation is irreversible.

```dart
final Identify identify = Identify()
    ..clearAll();
amplitude.identify(identify);
```

## Autocapture

The SDK tracks sessions, app lifecycle events, deep links, page views, and marketing attribution automatically without manual instrumentation. Configure this behavior with the `autocapture` parameter using `AutocaptureDisabled()`, `AutocaptureEnabled()`, or `AutocaptureOptions()`.

{% callout type="deprecated" %}
`defaultTracking` and `DefaultTrackingOptions` are deprecated. Use `autocapture` instead. Existing code that passes `defaultTracking` continues to work: when you don't set `autocapture` explicitly, the SDK derives it from `defaultTracking`. If you pass both, `autocapture` takes precedence.
{% /callout %}

When you omit both `autocapture` and `defaultTracking`, the SDK enables session tracking by default. On Web, it also enables page view and attribution tracking.

The SDK supports the following autocapture options:

| Option          | Platforms       | Default | Description                                                                                                                                                                                                 |
| --------------- | --------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sessions`      | All             | `true`  | Session start and end events. Refer to [Track sessions](#track-sessions).                                                                                                                                   |
| `appLifecycles` | iOS, Android    | `false` | Application installed, updated, opened, and backgrounded events. Refer to [Track application lifecycles](#track-application-lifecycles).                                                                    |
| `deepLinks`     | Android         | `false` | Deep link opened events. iOS doesn't map this flag. Refer to [Track deep links](#track-deep-links).                                                                                                         |
| `pageViews`     | Web             | `true`  | Page view events when the URL changes. Refer to [Page views](#page-views).                                                                                                                                 |
| `attribution`   | Web             | `true`  | Marketing attribution parameters from URL query strings. Refer to [Attribution](#attribution).                                                                                                                |

### Enable autocapture

To enable all autocapture features on every platform, use `AutocaptureEnabled()`:

```dart
Amplitude(
  Configuration(
    apiKey: 'YOUR-API-KEY',
    autocapture: AutocaptureEnabled(),
  )
);
```

On iOS and Android, `AutocaptureEnabled()` enables sessions, app lifecycles, and deep links. On Web, it also enables page views and attribution.

### Disable autocapture

To disable all autocapture features, use `AutocaptureDisabled()`:

```dart
Amplitude(
  Configuration(
    apiKey: 'YOUR-API-KEY',
    autocapture: AutocaptureDisabled(),
  )
);
```

### Configure autocapture

Use `AutocaptureOptions` for granular control:

```dart
Amplitude(
  Configuration(
    apiKey: 'YOUR-API-KEY',
    autocapture: AutocaptureOptions(
      sessions: true,
      appLifecycles: true,
      deepLinks: true,
      pageViews: PageViewsOptions(
        trackHistoryChanges: 'pathOnly',
        eventType: '[Amplitude] Page Viewed',
      ),
      attribution: AttributionOptions(
        excludeReferrers: ['example.com'],
        initialEmptyValue: 'NONE',
        resetSessionOnNewCampaign: true,
      ),
    ),
  )
);
```

{% callout type="warning" heading="" %}
Amplitude may add more autocapture events in a future version, and `AutocaptureEnabled()` enables tracking for those events.
{% /callout %}

### Track sessions

When you set `sessions` to `true`, Amplitude tracks session start and session end events. When you set `sessions` to `false`, Amplitude tracks `sessionId` only.

```dart
Amplitude(
  Configuration(
    apiKey: 'YOUR-API-KEY',
    autocapture: AutocaptureOptions(
      sessions: true,
    )
  )
);
```

### Track application lifecycles

When you set `appLifecycles` to `true`, Amplitude tracks application lifecycle events on iOS and Android.

```dart
Amplitude(
  Configuration(
    apiKey: 'YOUR-API-KEY',
    autocapture: AutocaptureOptions(
      appLifecycles: true,
    )
  )
);
```

After you enable this setting, Amplitude tracks the following events:

- `[Amplitude] Application Installed`: fires when a user opens the application for the first time right after installation.
- `[Amplitude] Application Updated`: fires when a user opens the application after updating it.
- `[Amplitude] Application Opened`: fires when a user launches or foregrounds the application after the first open.
- `[Amplitude] Application Backgrounded`: fires when a user backgrounds the application.

Tracked event properties include: `[Amplitude] Version`, `[Amplitude] Build`, `[Amplitude] Previous Version`, `[Amplitude] Previous Build`, `[Amplitude] From Background`.

### Track deep links

{% callout type="note" heading="" %}
Deep link tracking is available on Android only. The iOS native SDK doesn't expose deep links as an autocapture option, so the Flutter SDK ignores the `deepLinks` flag on iOS.
{% /callout %}

When you set `deepLinks` to `true`, Amplitude tracks events related to deep links in your Android application.

```dart
Amplitude(
  Configuration(
    apiKey: 'YOUR-API-KEY',
    autocapture: AutocaptureOptions(
      deepLinks: true,
    )
  )
);
```

After you enable this setting, Amplitude tracks the `[Amplitude] Deep Link Opened` event with the URL and referrer information. Tracked event properties include: `[Amplitude] Link URL`, `[Amplitude] Link Referrer`.

### Page views

Configure page view tracking on Web with `PageViewsOptions`:

| Option                | Type     | Description                                                                                                                                     | Default |
| --------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `trackHistoryChanges` | `String` | Track page views on navigation changes. Options: `'all'` (track all URL changes including fragments) or `'pathOnly'` (track only path changes). | `'all'` |
| `eventType`           | `String` | Custom event type for page view events. If not set or set to `''` (empty string), defaults to `'[Amplitude] Page Viewed'`.                      | `''`    |

```dart
autocapture: AutocaptureOptions(
  pageViews: PageViewsOptions(
    trackHistoryChanges: 'pathOnly',
    eventType: 'Page View',
  ),
)
```

To disable page view tracking, use `PageViewsDisabled()`:

```dart
autocapture: AutocaptureOptions(
  pageViews: PageViewsDisabled(),
)
```

### Attribution

Configure marketing attribution tracking on Web with `AttributionOptions`:

| Option                      | Type           | Description                                                                           | Default   |
| --------------------------- | -------------- | ------------------------------------------------------------------------------------- | --------- |
| `excludeReferrers`          | `List<String>` | List of referrer domains to exclude from attribution tracking.                        | `null`    |
| `initialEmptyValue`         | `String`       | Value to represent undefined initial campaign parameters for first-touch attribution. | `'EMPTY'` |
| `resetSessionOnNewCampaign` | `bool`         | Start a new session when campaign parameters change.                                  | `false`   |

```dart
autocapture: AutocaptureOptions(
  attribution: AttributionOptions(
    excludeReferrers: ['example.com', 'internal.com'],
    initialEmptyValue: 'NONE',
    resetSessionOnNewCampaign: true,
  ),
)
```

To disable attribution tracking, use `AttributionDisabled()`:

```dart
autocapture: AutocaptureOptions(
  attribution: AttributionDisabled(),
)
```

## User groups

Amplitude supports assigning users to groups and running queries, such as Count by Distinct, on those groups. If at least one member of the group has performed the specific event, the count includes the group.

For example, group your users by the organization they belong to using an 'orgId'. Joe is in 'orgId' '10', and Sue is in 'orgId' '15'. Sue and Joe both perform a certain event. You can query their organizations in the Event Segmentation Chart.

When setting groups, define a `groupType` and `groupName`. In the previous example, 'orgId' is the `groupType` and '10' and '15' are the values for `groupName`. Another example of a `groupType` could be 'sport' with `groupName` values like 'tennis' and 'baseball'.

Setting a group also sets the `groupType:groupName` as a user property and overwrites any existing `groupName` value for that user's `groupType` and the corresponding user property value. `groupType` is a string, and `groupName` can be either a string or an array of strings, where the array indicates that a user is in multiple groups.

{% callout type="example" heading="" %}
If Joe is in 'orgId' '15', the `groupName` is '15'.

```dart
// set group with a single group name
amplitude.setGroup('orgId', '15');
```

If Joe is in 'sport' 'tennis' and 'soccer', the `groupName` is '["tennis", "soccer"]'.

```dart
// set group with multiple group names
amplitude.setGroup('sport', ['tennis', 'soccer']);
```

{% /callout %}

You can also set event-level groups by passing an `Event` Object with `groups` to `track`. With event-level groups, the group designation applies only to the specific logged event and doesn't persist on the user unless you set the group explicitly with `setGroup`.

```dart
amplitude.track(BaseEvent('event type',
    eventProperties: {'event property': 'event property value'},
    groups: {'ordId': '15'}));
```

## Group identify

Use the Group Identify API to set or update the properties of particular groups. Keep these considerations in mind:

- Updates affect only future events, and don't update historical events.
- You can track up to 5 unique group types and 10 total groups.

The `groupIdentify` method accepts a group type string parameter, a group name object parameter, and an Identify object that Amplitude applies to the group.

```dart
final groupType = 'plan';
final groupName = 'enterprise';

final identify = Identify().set('key', 'value');
amplitude.groupIdentify(groupType, groupName, identify);
```

## Track revenue

Amplitude can track revenue generated by a user. Amplitude tracks revenue through distinct revenue objects, which have special fields that Amplitude's Event Segmentation and Revenue LTV charts use. Amplitude then displays revenue data in the platform automatically. Revenue objects support the following special properties, and also support user-defined properties through the `eventProperties` field.

```dart
final revenue = Revenue()
  ..productId = 'com.company.productId'
  ..price = 3.99
  ..quantity = 3;
amplitude.revenue(revenue);
```

| Name               | Description                                                                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `productId`        | Optional. String. An identifier for the product. Amplitude recommends something like the Google Play Store product ID. Defaults to `null`. |
| `quantity `        | Required. Integer. The quantity of products purchased. Note: revenue = quantity \* price. Defaults to 1.                                   |
| `price `           | Required. Double. The price of the products purchased, and this can be negative. Note: revenue = quantity \* price. Defaults to `null`.    |
| `revenueType`      | Optional, but required for revenue verification. String. The revenue type (for example, tax, refund, income). Defaults to `null`.          |
| `receipt`          | Optional. String. The receipt identifier of the revenue. For example, "123456". Defaults to `null`.                                        |
| `receiptSignature` | Optional, but required for revenue verification. String. Defaults to `null`.                                                               |

## Custom user ID

If your app has a login system you want to track users with, call `setUserId` at any time.

{% callout type="note" heading="Sending events" %}
This SDK uses the [HTTP V2](/docs/apis/analytics/http-v2) API and follows the same constraints for events. Make sure all events logged in the SDK contain at least one of `deviceId` (included by default) or `userId`, and follow the HTTP API's constraints on each of those fields.

To prevent instrumentation issues, device IDs and user IDs must be strings with a length of 5 characters or more. If an event contains a device ID or user ID that's too short, Amplitude removes the ID value from the event. If the event doesn't have a `userId` or `deviceId` value, Amplitude may reject the upload with a 400 status. Override the default minimum length of 5 characters by setting the `minIdLength` config option.
{% /callout %}

```dart
amplitude.setUserId('user@amplitude.com');
```

## Custom device ID

Assign a new device ID using `deviceId`. When you set a custom device ID, make sure the value is sufficiently unique. Amplitude recommends using a UUID.

{% callout type="note" heading="Sending events" %}
This SDK uses the [HTTP V2](/docs/apis/analytics/http-v2) API and follows the same constraints for events. Make sure all events logged in the SDK contain at least one of `deviceId` (included by default) or `userId`, and follow the HTTP API's constraints on each of those fields.

To prevent instrumentation issues, device IDs and user IDs must be strings with a length of 5 characters or more. If an event contains a device ID or user ID that's too short, Amplitude removes the ID value from the event. If the event doesn't have a `userId` or `deviceId` value, Amplitude may reject the upload with a 400 status. Override the default minimum length of 5 characters by setting the `minIdLength` config option.
{% /callout %}

```dart
amplitude.setDeviceId('your-unique-device-id');
```

## Reset when a user logs out

`reset` is a shortcut to anonymize users after they log out. It does the following:

- Sets `userId` to `null`.
- Sets `deviceId` to a new value based on the current configuration.

With an empty `userId` and a new `deviceId`, the current user appears as a new user in the dashboard.

```dart
amplitude.reset();
```
