> ## Documentation Index
> Fetch the complete documentation index at: https://docs.seasonlabs.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Flutter SDK quickstart

> Create a persistent mobile visitor and send it to your backend.

`era_flutter` creates and stores a `visitorId`. Your backend sends that ID and
the conversation to Era with the Node SDK.

<Warning>
  Never put a secret Node SDK API key in your Flutter app.
</Warning>

<Steps>
  <Step title="Install">
    Add the package to `pubspec.yaml`:

    ```yaml theme={null}
    dependencies:
      era_flutter: ^0.1.0
      http: ^1.5.0
    ```
  </Step>

  <Step title="Create the client">
    ```dart theme={null}
    import 'package:era_flutter/era_flutter.dart';

    final era = EraFlutter(
      baseUrl: 'https://your-era-endpoint.com',
      publishableKey: 'your_publishable_key',
    );
    ```

    A publishable key can be included in the app.
  </Step>

  <Step title="Initialize the visitor">
    ```dart theme={null}
    final visitorId = await era.init();
    ```

    The SDK reuses the visitor across app launches when preferences are
    available.
  </Step>

  <Step title="Send the visitor to your backend">
    ```dart theme={null}
    import 'dart:convert';

    import 'package:http/http.dart' as http;

    await http.post(
      Uri.parse('https://your-app.example.com/api/chat'),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({
        'messages': messages,
        'visitorId': visitorId,
        'sessionId': sessionId,
      }),
    );
    ```
  </Step>
</Steps>

For the server-side integration flow, see the
[Node SDK quickstart](/quickstart).

## Verify email or phone

Your app owns the verification UI:

```dart theme={null}
final challenge = await era.startVerification(
  VerificationType.email,
  'person@example.com',
);

final result = await era.confirmVerification(
  challenge.challengeId,
  enteredCode,
);
```

Use `VerificationType.phone` with an E.164 phone number. Use
`resendVerification()` only after a user action.

The SDK does not store codes or challenge details. Keep them only in temporary
UI state. `eraEndUserId` is a continuity hint, not proof that the user is
authenticated in your app.

## Reset and close

Reset the visitor after logout, account switching, or a shared-device user
change:

```dart theme={null}
final replacementVisitorId = await era.resetVisitor();
```

Call `close()` when you are finished with the client:

```dart theme={null}
era.close();
```

API and network failures throw `EraFlutterException`. Inspect `code`,
`message`, `retryable`, and `statusCode`.

## Next steps

<CardGroup cols={2}>
  <Card title="Identity lifecycle" icon="fingerprint" href="/flutter-sdk/identity">
    Learn about verification, reset, and cleanup.
  </Card>

  <Card title="Flutter SDK reference" icon="code" href="/flutter-sdk/reference">
    See every client method and option.
  </Card>
</CardGroup>
