diff --git a/README.md b/README.md
index 99e6944f..ef8ab4bf 100644
--- a/README.md
+++ b/README.md
@@ -8,16 +8,43 @@
+
-# Clerk Dart and Flutter SDKs
-The official [Clerk](https://clerk.com) Flutter/Dart client library.
+[](https://clerk.com/discord)
+[](https://clerk.com/docs)
+[](https://twitter.com/intent/follow?screen_name=Clerk)
+[](https://github.com/invertase/melos)
+
-* [clerk_auth](./packages/clerk_auth): Dart SDK
-* [clerk_flutter](./packages/clerk_flutter): Flutter SDK
+# Clerk Flutter and Dart SDKs
+**Clerk helps developers build user management. We provide streamlined user experiences for your users to sign up, sign in, and manage their profiles.**
-### License
+> ### β οΈ Beta Notice
+> These SDKs are currently in Beta. Breaking changes should be expected until the first stable release (1.0.0). Please [file any issues you encounter](https://github.com/clerk/clerk-sdk-flutter/issues).
-These SDKs are licensed under the MIT license found in the [LICENSE](./LICENSE) file.
+
+
+
+
+ The clerk_flutter example app
+
+
+---
+
+## π¦ Packages
+
+| Package | Description | Pub |
+|---------|-------------|-----|
+| [clerk_auth](./packages/clerk_auth) | Dart SDK for Clerk authentication | [](https://pub.dev/packages/clerk_auth) |
+| [clerk_flutter](./packages/clerk_flutter) | Flutter UI components for Clerk authentication | [](https://pub.dev/packages/clerk_flutter) |
+
+
+
+## π License
+
+This project is licensed under the MIT license.
+
+See [LICENSE](./LICENSE) for more information.
diff --git a/assets/example-dark.png b/assets/example-dark.png
new file mode 100644
index 00000000..b8f9c1e1
Binary files /dev/null and b/assets/example-dark.png differ
diff --git a/assets/example-light.png b/assets/example-light.png
new file mode 100644
index 00000000..8de27064
Binary files /dev/null and b/assets/example-light.png differ
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 00000000..01db3603
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,240 @@
+# Clerk SDK Documentation
+
+Welcome to the comprehensive documentation for the Clerk SDK for Flutter and Dart.
+
+## π Documentation Structure
+
+This documentation is organized into two main sections:
+
+### π― [clerk_auth](./clerk_auth/) - Core Dart SDK
+
+The foundational authentication library that works with any Dart application.
+
+**Start here if you're:**
+- Building a Dart CLI application
+- Integrating Clerk into a non-Flutter Dart project
+- Understanding the core authentication logic
+- Implementing custom UI or integrations
+
+**Key Documentation:**
+- [**Auth API**](./clerk_auth/auth.md) - Complete authentication methods (sign-in, sign-up, OAuth, passkeys, sessions, etc.)
+- [**AuthConfig**](./clerk_auth/auth_config.md) - SDK configuration and initialization
+- [**Persistor**](./clerk_auth/persistor.md) - Custom storage implementations
+- [**HttpService**](./clerk_auth/http_service.md) - Custom HTTP client implementations
+
+### π¨ [clerk_flutter](./clerk_flutter/) - Flutter Widgets
+
+Pre-built Flutter widgets and UI components for rapid integration.
+
+**Start here if you're:**
+- Building a Flutter mobile or web application
+- Looking for pre-built authentication UI
+- Wanting quick integration with minimal code
+- Customizing the appearance of auth flows
+
+**Key Documentation:**
+- [**ClerkAuth**](./clerk_flutter/clerk_auth.md) - Root widget and state management
+- [**ClerkAuthentication**](./clerk_flutter/clerk_authentication.md) - Complete pre-built auth UI
+- [**ClerkUserButton**](./clerk_flutter/clerk_user_button.md) - User profile and session management
+- [**ClerkAuthBuilder**](./clerk_flutter/clerk_auth_builder.md) - Custom UI with builder pattern
+- [**ClerkTheme**](./clerk_flutter/clerk_theme.md) - Theming and customization
+
+---
+
+## π Quick Start
+
+### For Flutter Applications
+
+1. **Add dependencies** to your `pubspec.yaml`:
+ ```yaml
+ dependencies:
+ clerk_flutter: ^0.0.14-beta
+ ```
+
+2. **Wrap your app** with `ClerkAuth`:
+ ```dart
+ MaterialApp(
+ builder: ClerkAuth.materialAppBuilder(
+ config: ClerkAuthConfig(
+ publishableKey: 'pk_test_...',
+ ),
+ ),
+ home: const HomePage(),
+ )
+ ```
+
+3. **Use pre-built UI** or build custom:
+ ```dart
+ // Pre-built UI
+ ClerkSignedOut(
+ child: const ClerkAuthentication(),
+ )
+
+ // Custom UI
+ ClerkAuthBuilder(
+ signedInBuilder: (context, authState) {
+ return Text('Welcome, ${authState.user?.fullName}!');
+ },
+ signedOutBuilder: (context, authState) {
+ return const ClerkAuthentication();
+ },
+ )
+ ```
+
+π **[Full Flutter Guide β](./clerk_flutter/README.md)**
+
+### For Dart Applications
+
+1. **Add dependency** to your `pubspec.yaml`:
+ ```yaml
+ dependencies:
+ clerk_auth: ^0.0.14-beta
+ ```
+
+2. **Initialize** the Auth instance:
+ ```dart
+ import 'package:clerk_auth/clerk_auth.dart';
+
+ final auth = Auth(
+ config: AuthConfig(publishableKey: 'pk_test_...'),
+ );
+ await auth.initialize();
+ ```
+
+3. **Authenticate** users:
+ ```dart
+ // Email + Password sign-in
+ await auth.attemptSignIn(identifier: 'user@example.com');
+ await auth.attemptSignIn(password: 'password123');
+
+ // Check auth state
+ if (auth.isSignedIn) {
+ print('User: ${auth.user?.fullName}');
+ }
+ ```
+
+π **[Full Dart Guide β](./clerk_auth/README.md)**
+
+---
+
+## π Documentation Index
+
+### clerk_auth (Core SDK)
+
+| Document | Description |
+|----------|-------------|
+| [README](./clerk_auth/README.md) | Overview and getting started |
+| [Auth](./clerk_auth/auth.md) | Complete API reference for authentication methods |
+| [AuthConfig](./clerk_auth/auth_config.md) | Configuration options and initialization |
+| [Persistor](./clerk_auth/persistor.md) | Storage interface for sessions and tokens |
+| [HttpService](./clerk_auth/http_service.md) | HTTP client interface for custom networking |
+
+### clerk_flutter (Flutter Widgets)
+
+| Document | Description |
+|----------|-------------|
+| [README](./clerk_flutter/README.md) | Overview and getting started |
+| [ClerkAuth](./clerk_flutter/clerk_auth.md) | Root widget and state management |
+| [ClerkAuthBuilder](./clerk_flutter/clerk_auth_builder.md) | Builder pattern for custom UI |
+| [ClerkAuthentication](./clerk_flutter/clerk_authentication.md) | Pre-built authentication UI |
+| [ClerkUserButton](./clerk_flutter/clerk_user_button.md) | User profile button and menu |
+| [ClerkOrganizationList](./clerk_flutter/clerk_organization_list.md) | Organization management UI |
+| [ClerkSignedIn](./clerk_flutter/clerk_signed_in.md) | Conditional rendering (signed in) |
+| [ClerkSignedOut](./clerk_flutter/clerk_signed_out.md) | Conditional rendering (signed out) |
+| [ClerkErrorListener](./clerk_flutter/clerk_error_listener.md) | Error handling and display |
+| [ClerkAuthConfig](./clerk_flutter/clerk_auth_config.md) | Flutter-specific configuration |
+| [ClerkTheme](./clerk_flutter/clerk_theme.md) | Theming and customization |
+
+---
+
+## π― Common Use Cases
+
+### Authentication Flows
+
+- **[Email + Password Sign-In](./clerk_auth/auth.md#email--password-sign-in)** - Traditional authentication
+- **[Email Code Sign-In](./clerk_auth/auth.md#email-code-sign-in)** - Passwordless with verification code
+- **[Phone Code Sign-In](./clerk_auth/auth.md#phone-code-sign-in)** - SMS-based authentication
+- **[OAuth Sign-In](./clerk_auth/auth.md#oauth-sign-in)** - Social login (Google, Apple, GitHub, etc.)
+- **[Passkey Authentication](./clerk_auth/auth.md#passkey-authentication)** - WebAuthn/FIDO2
+- **[Multi-Factor Authentication](./clerk_auth/auth.md#multi-factor-authentication)** - 2FA with SMS or TOTP
+
+### Session Management
+
+- **[Session Handling](./clerk_auth/auth.md#session-management)** - Managing user sessions
+- **[Multi-Session Support](./clerk_auth/auth.md#multi-session-management)** - Multiple accounts
+- **[Token Management](./clerk_auth/auth.md#token-management)** - Access tokens and JWTs
+
+### User Management
+
+- **[User Profile](./clerk_auth/auth.md#user-management)** - Updating user information
+- **[Email Management](./clerk_auth/auth.md#email-management)** - Adding/removing emails
+- **[Phone Management](./clerk_auth/auth.md#phone-management)** - Adding/removing phone numbers
+- **[External Accounts](./clerk_auth/auth.md#external-account-management)** - OAuth connections
+
+### Organization Features
+
+- **[Organization Management](./clerk_auth/auth.md#organization-management)** - Creating and managing orgs
+- **[Organization Switching](./clerk_auth/auth.md#switching-organizations)** - Multi-org support
+- **[Organization UI](./clerk_flutter/clerk_organization_list.md)** - Pre-built organization widgets
+
+---
+
+## π Key Concepts
+
+### Re-entrant Authentication
+
+The `attemptSignIn()` and `attemptSignUp()` methods are **re-entrant**, meaning you call them multiple times with different parameters to progress through the authentication flow:
+
+```dart
+// Step 1: Provide identifier
+await auth.attemptSignIn(identifier: 'user@example.com');
+
+// Step 2: Provide password
+await auth.attemptSignIn(password: 'password123');
+
+// Step 3: If 2FA enabled, provide code
+await auth.attemptSignIn(code: '123456');
+```
+
+π **[Learn more about re-entrant flows β](./clerk_auth/auth.md#re-entrant-methods)**
+
+### Transfer Flow
+
+When using OAuth or ID token authentication, Clerk uses a "transfer flow" to securely complete authentication:
+
+```dart
+// 1. Initiate OAuth
+final transfer = await auth.oauthSignIn(strategy: Strategy.oauth_google);
+
+// 2. Open browser to transfer.authUrl
+
+// 3. Complete after redirect
+await auth.completeOAuthSignIn(transfer: transfer);
+```
+
+π **[Learn more about transfer flow β](./clerk_auth/auth.md#transfer-flow)**
+
+---
+
+## π‘ Best Practices
+
+1. **Use environment variables** for publishable keys
+2. **Handle errors** with `ClerkErrorListener` (Flutter) or try-catch blocks (Dart)
+3. **Respect re-entrant flows** - call `attemptSignIn`/`attemptSignUp` multiple times
+4. **Check auth state** before accessing user/session data
+5. **Implement proper loading states** during authentication
+6. **Test all authentication strategies** enabled in your Clerk Dashboard
+7. **Customize themes** to match your brand (Flutter)
+
+---
+
+## π Support
+
+- **Clerk Dashboard**: [https://dashboard.clerk.com](https://dashboard.clerk.com)
+- **Clerk Documentation**: [https://clerk.com/docs](https://clerk.com/docs)
+- **GitHub Issues**: Report bugs and request features
+
+---
+
+*Documentation generated for Clerk SDK version 0.0.14-beta*
+
diff --git a/docs/clerk_auth/README.md b/docs/clerk_auth/README.md
new file mode 100644
index 00000000..8609a7f1
--- /dev/null
+++ b/docs/clerk_auth/README.md
@@ -0,0 +1,301 @@
+# Clerk Auth Documentation
+
+Welcome to the comprehensive documentation for the `clerk_auth` package. This documentation covers all public APIs and provides detailed usage examples.
+
+## Documentation Index
+
+### Core Classes
+
+1. **[Auth](auth.md)** - The main authentication class
+ - All authentication methods (sign in, sign up, OAuth, passkeys)
+ - Session management
+ - User management
+ - Organization management
+ - **Special focus on re-entrant methods**: `attemptSignIn()` and `attemptSignUp()`
+
+2. **[AuthConfig](auth_config.md)** - Configuration for the Auth class
+ - Required and optional parameters
+ - Polling and refresh settings
+ - Telemetry configuration
+ - Complete configuration examples
+
+3. **[Persistor](persistor.md)** - Persistence interface for authentication state
+ - Abstract interface definition
+ - Built-in implementations (`Persistor.none`, `DefaultPersistor`)
+ - Custom implementation examples
+ - Storage keys used by Clerk
+
+4. **[HttpService](http_service.md)** - HTTP communication interface
+ - Abstract interface definition
+ - Default implementation
+ - Custom implementation examples (logging, retry, mocking)
+ - HTTP methods and request handling
+
+---
+
+## Quick Start
+
+### Basic Setup
+
+```dart
+import 'package:clerk_auth/clerk_auth.dart';
+import 'package:path_provider/path_provider.dart';
+
+Future main() async {
+ // Create configuration
+ final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: DefaultPersistor(
+ getCacheDirectory: getApplicationDocumentsDirectory,
+ ),
+ );
+
+ // Create and initialize Auth
+ final auth = Auth(config: config);
+ await auth.initialize();
+
+ // Use auth for authentication
+ await auth.attemptSignIn(
+ strategy: Strategy.password,
+ identifier: 'user@example.com',
+ password: 'password123',
+ );
+
+ if (auth.isSignedIn) {
+ print('Welcome, ${auth.user?.fullName}!');
+ }
+}
+```
+
+---
+
+## Key Concepts
+
+### Re-entrant Authentication Methods
+
+The `attemptSignIn()` and `attemptSignUp()` methods are designed to be **re-entrant**, meaning they can be called multiple times with different parameters as the user progresses through the authentication flow.
+
+**Example: Multi-step Sign In**
+```dart
+// Step 1: Start with email
+await auth.attemptSignIn(
+ strategy: Strategy.emailCode,
+ identifier: 'user@example.com',
+);
+
+// Step 2: Submit verification code
+await auth.attemptSignIn(
+ strategy: Strategy.emailCode,
+ code: '123456',
+);
+
+// Step 3: If 2FA required, submit 2FA code
+if (auth.signIn?.needsSecondFactor == true) {
+ await auth.attemptSignIn(
+ strategy: Strategy.totp,
+ code: '654321',
+ );
+}
+```
+
+### Transfer Flow
+
+When using OAuth or ID token authentication, users may need to "transfer" between sign-in and sign-up flows:
+
+```dart
+// Try sign in with Apple
+await auth.idTokenSignIn(
+ provider: IdTokenProvider.apple,
+ idToken: credential.identityToken!,
+);
+
+// If user doesn't exist, transfer to sign up
+if (auth.signIn?.isTransferable == true) {
+ await auth.transfer();
+}
+```
+
+### State Management
+
+The Auth class maintains state through the `Client` object:
+- `client.signIn` - Active sign-in flow
+- `client.signUp` - Active sign-up flow
+- `client.sessions` - Active sessions
+- `session.user` - Current user
+
+---
+
+## Common Use Cases
+
+### Email + Password Authentication
+
+```dart
+// Sign up
+await auth.attemptSignUp(
+ strategy: Strategy.emailCode,
+ emailAddress: 'user@example.com',
+ password: 'SecurePass123!',
+ passwordConfirmation: 'SecurePass123!',
+ firstName: 'John',
+ lastName: 'Doe',
+);
+
+// Verify email
+await auth.attemptSignUp(
+ strategy: Strategy.emailCode,
+ code: '123456',
+);
+
+// Sign in
+await auth.attemptSignIn(
+ strategy: Strategy.password,
+ identifier: 'user@example.com',
+ password: 'SecurePass123!',
+);
+```
+
+### OAuth Authentication
+
+```dart
+// Google Sign In
+await auth.oauthSignIn(
+ strategy: Strategy.oauthGoogle,
+ redirect: Uri.parse('myapp://oauth-callback'),
+);
+
+// After redirect, complete sign in
+await auth.completeOAuthSignIn(token: rotatingTokenNonce);
+```
+
+### Passkey Authentication
+
+```dart
+// Create passkey
+final passkey = await auth.createPasskey();
+// ... use passkey library to register ...
+await auth.attemptPasskeyVerification(passkey!, credentialJson);
+
+// Sign in with passkey
+await auth.attemptSignIn(strategy: Strategy.passkey);
+// ... use passkey library to authenticate ...
+await auth.attemptSignIn(
+ strategy: Strategy.passkey,
+ passkeyCredential: credentialJson,
+);
+```
+
+### Session Management
+
+```dart
+// Get session token
+final token = await auth.sessionToken();
+print('JWT: ${token.jwt}');
+
+// Listen to token updates
+auth.sessionTokenStream.listen((token) {
+ // Update your API client with new token
+});
+
+// Switch sessions
+await auth.activate(anotherSession);
+
+// Sign out
+await auth.signOut();
+```
+
+---
+
+## Architecture
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β Auth β
+β - Main authentication logic β
+β - State management β
+β - Public API β
+βββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
+ β
+ β uses
+ β
+ βββββββββββββββ΄ββββββββββββββ
+ β β
+ βΌ βΌ
+βββββββββββββββ βββββββββββββββ
+β AuthConfig β β Api β
+β β β (internal) β
+ββββββββ¬βββββββ βββββββββββββββ
+ β
+ β contains
+ β
+ βββββ΄βββββ¬βββββββββββ
+ β β β
+ βΌ βΌ βΌ
+ββββββββ ββββββββββ βββββββββββββββ
+βPersisβ β Http β β Retry β
+β tor β βService β β Options β
+ββββββββ ββββββββββ βββββββββββββββ
+```
+
+---
+
+## Best Practices
+
+1. **Always initialize before use**: Call `auth.initialize()` before any other operations
+2. **Use appropriate persistor**: `DefaultPersistor` for production, `Persistor.none` for testing
+3. **Handle errors gracefully**: Wrap auth calls in try-catch or override `handleError()`
+4. **Leverage re-entrant methods**: Call `attemptSignIn()`/`attemptSignUp()` multiple times as needed
+5. **Check transfer status**: After OAuth/ID token auth, check `isTransferable` and call `transfer()`
+6. **Clean up resources**: Call `auth.terminate()` when disposing
+7. **Monitor session tokens**: Use `sessionTokenStream` to keep tokens fresh
+
+---
+
+## Testing
+
+### Unit Testing
+
+```dart
+import 'package:clerk_auth/clerk_auth.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+ test('sign in test', () async {
+ final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: Persistor.none,
+ sessionTokenPolling: false,
+ clientRefreshPeriod: Duration.zero,
+ telemetryPeriod: Duration.zero,
+ );
+
+ final auth = Auth(config: config);
+ await auth.initialize();
+
+ // Test authentication flows
+
+ auth.terminate();
+ });
+}
+```
+
+---
+
+## Additional Resources
+
+- [Clerk Dashboard](https://dashboard.clerk.com/)
+- [Clerk API Reference](https://clerk.com/docs/reference/backend-api)
+- [Flutter SDK Guide](https://clerk.com/docs/quickstarts/flutter)
+- [clerk_auth on pub.dev](https://pub.dev/packages/clerk_auth)
+
+---
+
+## Version
+
+*Documentation generated for clerk_auth version 0.0.14-beta*
+
+---
+
+## Contributing
+
+Found an issue or want to improve the documentation? Please open an issue or pull request on the [GitHub repository](https://github.com/clerk/clerk-sdk-flutter).
+
diff --git a/docs/clerk_auth/auth.md b/docs/clerk_auth/auth.md
new file mode 100644
index 00000000..818545df
--- /dev/null
+++ b/docs/clerk_auth/auth.md
@@ -0,0 +1,1447 @@
+# Clerk Auth API Documentation
+
+This document provides comprehensive documentation for all public methods in the `Auth` class from `clerk_auth/lib/src/clerk_auth/auth.dart`.
+
+## Overview
+
+The `Auth` class is the core of the Clerk authentication system for Dart/Flutter applications. It provides a high-level API for managing user authentication, sessions, and user data.
+
+### Key Concepts
+
+**Re-entrant Methods**: The `attemptSignIn()` and `attemptSignUp()` methods are designed to be **re-entrant**, meaning they can be called multiple times with different parameters as the user progresses through the authentication flow. This design allows for flexible, step-by-step authentication processes.
+
+**State Management**: The Auth class maintains the current authentication state through the `Client` object, which contains:
+- `SignIn` object (during sign-in flow)
+- `SignUp` object (during sign-up flow)
+- `User` object (when signed in)
+- `Session` objects (active sessions)
+
+**Transfer Flow**: When using OAuth or ID token authentication, users may need to "transfer" between sign-in and sign-up flows if they don't exist yet (or already exist). Use the `transfer()` method to handle this seamlessly.
+
+## Table of Contents
+
+- [Initialization & Lifecycle](#initialization--lifecycle)
+- [Authentication State](#authentication-state)
+- [Sign In Methods](#sign-in-methods)
+- [Sign Up Methods](#sign-up-methods)
+- [OAuth Methods](#oauth-methods)
+- [Passkey Methods](#passkey-methods)
+- [Session Management](#session-management)
+- [User Management](#user-management)
+- [Organization Management](#organization-management)
+- [Password Management](#password-management)
+- [Advanced Methods](#advanced-methods)
+
+---
+
+## Initialization & Lifecycle
+
+### `initialize()`
+
+Initializes the Auth object. **Must be called before any other Auth methods.**
+
+```dart
+Future initialize()
+```
+
+**Example:**
+```dart
+final auth = Auth(config: AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: Persistor.none,
+));
+await auth.initialize();
+```
+
+**Behavior:**
+- Loads persisted client and environment data
+- Sets up periodic client refresh (if configured)
+- Starts session token polling (if enabled)
+- Retries fetching client/environment if initial fetch fails
+
+---
+
+### `terminate()`
+
+Disposes of the Auth object and cleans up resources.
+
+```dart
+void terminate()
+```
+
+**Example:**
+```dart
+auth.terminate();
+```
+
+**Behavior:**
+- Cancels all timers (polling, refresh, etc.)
+- Closes stream controllers
+- Terminates telemetry and API connections
+
+---
+
+## Authentication State
+
+### `isSignedIn`
+
+Returns whether a user is currently signed in.
+
+```dart
+bool get isSignedIn
+```
+
+**Example:**
+```dart
+if (auth.isSignedIn) {
+ print('User: ${auth.user?.fullName}');
+}
+```
+
+---
+
+### `isSigningIn`
+
+Returns whether a sign-in flow is currently in progress.
+
+```dart
+bool get isSigningIn
+```
+
+---
+
+### `isSigningUp`
+
+Returns whether a sign-up flow is currently in progress.
+
+```dart
+bool get isSigningUp
+```
+
+---
+
+### `client`
+
+The current Client object containing authentication state.
+
+```dart
+Client get client
+```
+
+**Example:**
+```dart
+final client = auth.client;
+print('Active sessions: ${client.sessions.length}');
+```
+
+---
+
+### `user`
+
+The currently signed-in User, or null if not signed in.
+
+```dart
+User? get user
+```
+
+---
+
+### `session`
+
+The current active Session, or null.
+
+```dart
+Session? get session
+```
+
+---
+
+### `signIn`
+
+The current SignIn object, or null.
+
+```dart
+SignIn? get signIn
+```
+
+---
+
+### `signUp`
+
+The current SignUp object, or null.
+
+```dart
+SignUp? get signUp
+```
+
+---
+
+### `organization`
+
+The current active Organization, or null.
+
+```dart
+Organization? get organization
+```
+
+---
+
+### `env`
+
+The Environment object containing Clerk account configuration.
+
+```dart
+Environment get env
+```
+
+---
+
+### `isNotAvailable`
+
+Returns whether the Auth object is not yet initialized.
+
+```dart
+bool get isNotAvailable
+```
+
+**Example:**
+```dart
+if (auth.isNotAvailable) {
+ print('Auth is still initializing...');
+}
+```
+
+---
+
+### `handleError()`
+
+Handles ClerkError exceptions when they occur. Override this method to customize error handling.
+
+```dart
+void handleError(Object error)
+```
+
+**Default Behavior:**
+- Throws the error
+
+**Example (Custom Error Handling):**
+```dart
+class MyAuth extends Auth {
+ MyAuth({required super.config});
+
+ @override
+ void handleError(Object error) {
+ if (error is ClerkError) {
+ // Log error instead of throwing
+ print('Clerk error: ${error.message}');
+ // Show user-friendly message
+ showErrorToUser(error.message);
+ } else {
+ // Re-throw non-Clerk errors
+ super.handleError(error);
+ }
+ }
+}
+```
+
+---
+
+### `update()`
+
+A method to be overridden by extension classes to handle state updates. Called automatically after most Auth operations.
+
+```dart
+void update()
+```
+
+**Example:**
+```dart
+class MyAuth extends Auth with ChangeNotifier {
+ MyAuth({required super.config});
+
+ @override
+ void update() {
+ super.update();
+ notifyListeners(); // Notify UI of changes
+ }
+}
+```
+
+---
+
+## Sign In Methods
+
+### `attemptSignIn()`
+
+**Re-entrant method** for progressively signing in a user. Can be called multiple times with updated parameters until sign-in is complete.
+
+```dart
+Future attemptSignIn({
+ required Strategy strategy,
+ String? identifier,
+ String? password,
+ String? code,
+ String? token,
+ String? redirectUrl,
+ String? passkeyCredential,
+})
+```
+
+**Parameters:**
+- `strategy`: The authentication strategy (e.g., `Strategy.emailCode`, `Strategy.password`)
+- `identifier`: Email, phone, or username
+- `password`: User's password (for password-based auth)
+- `code`: Verification code (for code-based strategies)
+- `token`: OAuth or ID token
+- `redirectUrl`: Redirect URL for email link strategy
+- `passkeyCredential`: Passkey credential JSON string
+
+**Example 1: Email + Password Sign In**
+```dart
+// Initial call with identifier and password
+await auth.attemptSignIn(
+ strategy: Strategy.password,
+ identifier: 'user@example.com',
+ password: 'SecurePass123!',
+);
+
+// If 2FA is required, call again with the code
+if (auth.signIn?.needsSecondFactor == true) {
+ await auth.attemptSignIn(
+ strategy: Strategy.emailCode,
+ code: '123456',
+ );
+}
+```
+
+**Example 2: Email Code Sign In (Re-entrant)**
+```dart
+// Step 1: Start sign-in with email
+await auth.attemptSignIn(
+ strategy: Strategy.emailCode,
+ identifier: 'user@example.com',
+);
+
+// Step 2: User receives code, submit it
+await auth.attemptSignIn(
+ strategy: Strategy.emailCode,
+ code: '123456',
+);
+```
+
+**Example 3: Password Reset**
+```dart
+// Step 1: Initiate password reset
+await auth.initiatePasswordReset(
+ identifier: 'user@example.com',
+ strategy: Strategy.resetPasswordEmailCode,
+);
+
+// Step 2: Submit code and new password
+await auth.attemptSignIn(
+ strategy: Strategy.resetPasswordEmailCode,
+ code: '123456',
+ password: 'NewSecurePass123!',
+);
+```
+
+**Example 4: Passkey Sign In**
+```dart
+// Step 1: Prepare passkey sign-in
+await auth.attemptSignIn(strategy: Strategy.passkey);
+
+// Step 2: Get passkey credential from authenticator
+final nonce = auth.signIn?.firstFactorVerification?.nonce;
+// ... use passkey library to get credential ...
+
+// Step 3: Complete sign-in with credential
+await auth.attemptSignIn(
+ strategy: Strategy.passkey,
+ passkeyCredential: credentialJson,
+);
+```
+
+**Re-entrant Behavior:**
+- The method intelligently handles the current state of the sign-in flow
+- Can be called multiple times as the user progresses through authentication steps
+- Automatically creates a SignIn object if one doesn't exist
+- Handles preparation and attempt phases based on the strategy and current state
+
+---
+
+### `initiatePasswordReset()`
+
+Initiates a password reset flow.
+
+```dart
+Future initiatePasswordReset({
+ required String identifier,
+ required Strategy strategy,
+})
+```
+
+**Example:**
+```dart
+await auth.initiatePasswordReset(
+ identifier: 'user@example.com',
+ strategy: Strategy.resetPasswordEmailCode,
+);
+```
+
+---
+
+### `idTokenSignIn()`
+
+Sign in with an ID token from a provider (e.g., Apple, Google).
+
+```dart
+Future idTokenSignIn({
+ required IdTokenProvider provider,
+ required String idToken,
+})
+```
+
+**Example:**
+```dart
+// Apple Sign In
+await auth.idTokenSignIn(
+ provider: IdTokenProvider.apple,
+ idToken: credential.identityToken!,
+);
+
+// Check if transfer needed (user doesn't exist)
+if (auth.signIn?.isTransferable == true) {
+ await auth.transfer(); // Switch to sign-up flow
+}
+```
+
+**Transfer Flow:**
+If the user doesn't exist, the verification status will be `transferable`. Call `transfer()` to switch to the sign-up flow.
+
+---
+
+## Sign Up Methods
+
+### `attemptSignUp()`
+
+**Re-entrant method** for progressively signing up a new user. Can be called multiple times with updated parameters until sign-up is complete.
+
+```dart
+Future attemptSignUp({
+ required Strategy strategy,
+ String? firstName,
+ String? lastName,
+ String? username,
+ String? emailAddress,
+ String? phoneNumber,
+ String? password,
+ String? passwordConfirmation,
+ String? code,
+ String? token,
+ String? signature,
+ String? redirectUrl,
+ Map? metadata,
+ bool? legalAccepted,
+})
+```
+
+**Parameters:**
+- `strategy`: The authentication strategy
+- `firstName`, `lastName`, `username`: User profile information
+- `emailAddress`, `phoneNumber`: Contact identifiers
+- `password`, `passwordConfirmation`: Password (must match)
+- `code`: Verification code
+- `token`: OAuth or ID token
+- `signature`: Email link signature
+- `redirectUrl`: Redirect URL for email link strategy
+- `metadata`: Custom metadata to attach to the user
+- `legalAccepted`: Legal consent acceptance (required if enabled in settings)
+
+**Example 1: Email + Password Sign Up (Re-entrant)**
+```dart
+// Step 1: Create sign-up with initial data
+await auth.attemptSignUp(
+ strategy: Strategy.emailCode,
+ emailAddress: 'newuser@example.com',
+ password: 'SecurePass123!',
+ passwordConfirmation: 'SecurePass123!',
+ firstName: 'John',
+ lastName: 'Doe',
+);
+
+// Step 2: Verify email with code
+await auth.attemptSignUp(
+ strategy: Strategy.emailCode,
+ code: '123456',
+);
+```
+
+**Example 2: Phone Number Sign Up**
+```dart
+// Step 1: Create sign-up
+await auth.attemptSignUp(
+ strategy: Strategy.phoneCode,
+ phoneNumber: '+1234567890',
+ firstName: 'Jane',
+ lastName: 'Smith',
+);
+
+// Step 2: Verify phone
+await auth.attemptSignUp(
+ strategy: Strategy.phoneCode,
+ code: '123456',
+);
+```
+
+**Example 3: Sign Up with Metadata**
+```dart
+await auth.attemptSignUp(
+ strategy: Strategy.emailCode,
+ emailAddress: 'user@example.com',
+ password: 'SecurePass123!',
+ passwordConfirmation: 'SecurePass123!',
+ metadata: {
+ 'referralCode': 'ABC123',
+ 'source': 'mobile_app',
+ },
+);
+```
+
+**Example 4: Sign Up with Legal Consent**
+```dart
+await auth.attemptSignUp(
+ strategy: Strategy.emailCode,
+ emailAddress: 'user@example.com',
+ password: 'SecurePass123!',
+ passwordConfirmation: 'SecurePass123!',
+ legalAccepted: true, // Required if legal consent is enabled
+);
+```
+
+**Re-entrant Behavior:**
+- Can be called multiple times to update sign-up data
+- Automatically handles verification preparation and attempts
+- Updates existing SignUp object if one exists
+- Creates new SignUp object on first call
+- Validates password confirmation matches password
+
+**Throws:**
+- `ClerkError` with code `passwordMatchError` if passwords don't match
+- `ClerkError` with code `legalAcceptanceRequired` if legal consent is required but not provided
+
+---
+
+### `idTokenSignUp()`
+
+Sign up with an ID token from a provider (e.g., Apple, Google).
+
+```dart
+Future idTokenSignUp({
+ required IdTokenProvider provider,
+ required String idToken,
+ String? firstName,
+ String? lastName,
+})
+```
+
+**Example:**
+```dart
+// Apple Sign Up
+await auth.idTokenSignUp(
+ provider: IdTokenProvider.apple,
+ idToken: credential.identityToken!,
+ firstName: credential.givenName,
+ lastName: credential.familyName,
+);
+
+// Check if transfer needed (user already exists)
+if (auth.signUp?.isTransferable == true) {
+ await auth.transfer(); // Switch to sign-in flow
+}
+```
+
+**Transfer Flow:**
+If the user already exists, the verification status will be `transferable`. Call `transfer()` to switch to the sign-in flow.
+
+---
+
+### `resendCode()`
+
+Resends a verification code for the given strategy.
+
+```dart
+Future resendCode(Strategy strategy)
+```
+
+**Example:**
+```dart
+// During sign-up or sign-in
+await auth.resendCode(Strategy.emailCode);
+```
+
+**Throws:**
+- `ClerkError` with code `noInitialCodeHasBeenSetUpToResend` if no code flow is active
+
+---
+
+## OAuth Methods
+
+### `oauthSignIn()`
+
+Prepares for sign-in via an OAuth provider.
+
+```dart
+Future oauthSignIn({
+ required Strategy strategy,
+ required Uri? redirect,
+})
+```
+
+**Example:**
+```dart
+await auth.oauthSignIn(
+ strategy: Strategy.oauthGoogle,
+ redirect: Uri.parse('myapp://oauth-callback'),
+);
+
+// The user will be redirected to the OAuth provider
+// After authentication, complete the flow with completeOAuthSignIn()
+```
+
+---
+
+### `completeOAuthSignIn()`
+
+Completes OAuth sign-in by presenting the token.
+
+```dart
+Future completeOAuthSignIn({
+ required String token,
+})
+```
+
+**Example:**
+```dart
+// After OAuth redirect
+await auth.completeOAuthSignIn(token: rotatingTokenNonce);
+```
+
+---
+
+### `oauthConnect()`
+
+Connects an external account via an OAuth provider to the current user.
+
+```dart
+Future oauthConnect({
+ required Strategy strategy,
+ required Uri? redirect,
+})
+```
+
+**Example:**
+```dart
+// Connect Google account to existing user
+await auth.oauthConnect(
+ strategy: Strategy.oauthGoogle,
+ redirect: Uri.parse('myapp://oauth-callback'),
+);
+```
+
+---
+
+### `deleteExternalAccount()`
+
+Deletes an external account connection.
+
+```dart
+Future deleteExternalAccount({
+ required ExternalAccount account,
+})
+```
+
+**Example:**
+```dart
+final googleAccount = auth.user?.externalAccounts
+ ?.firstWhere((acc) => acc.provider == 'google');
+if (googleAccount != null) {
+ await auth.deleteExternalAccount(account: googleAccount);
+}
+```
+
+---
+
+## Passkey Methods
+
+### `createPasskey()`
+
+Creates an unverified passkey for the current user.
+
+```dart
+Future createPasskey()
+```
+
+**Example:**
+```dart
+final passkey = await auth.createPasskey();
+if (passkey?.verification?.nonce case VerificationNonce nonce) {
+ // Use passkey library to register
+ final authenticator = PasskeyAuthenticator();
+ final challenge = RegisterRequestType(
+ challenge: nonce.challenge,
+ relyingParty: nonce.relyingParty.toRelyingPartyType(),
+ user: nonce.user!.toUserType(),
+ excludeCredentials: const [],
+ timeout: nonce.timeout,
+ );
+ final credential = await authenticator.register(challenge);
+
+ // Verify the passkey
+ await auth.attemptPasskeyVerification(passkey!, credential.toJsonString());
+}
+```
+
+---
+
+### `attemptPasskeyVerification()`
+
+Verifies a passkey with the provided credential.
+
+```dart
+Future attemptPasskeyVerification(
+ Passkey passkey,
+ String credential,
+)
+```
+
+**Example:**
+```dart
+await auth.attemptPasskeyVerification(passkey, credentialJson);
+```
+
+---
+
+## Session Management
+
+### `sessionToken()`
+
+Gets the current session token for an organization.
+
+```dart
+Future sessionToken({
+ Organization? organization,
+ String? templateName,
+})
+```
+
+**Example:**
+```dart
+// Get default session token
+final token = await auth.sessionToken();
+print('JWT: ${token.jwt}');
+
+// Get token for specific organization
+final orgToken = await auth.sessionToken(
+ organization: myOrganization,
+);
+
+// Get token with custom template
+final customToken = await auth.sessionToken(
+ templateName: 'my_custom_template',
+);
+```
+
+**Throws:**
+- `ClerkError` with code `noSessionTokenRetrieved` if token cannot be retrieved
+
+---
+
+### `sessionTokenStream`
+
+Stream of SessionTokens as they renew.
+
+```dart
+Stream get sessionTokenStream
+```
+
+**Example:**
+```dart
+auth.sessionTokenStream.listen((token) {
+ print('New token: ${token.jwt}');
+ // Update your API client with new token
+});
+```
+
+---
+
+### `activate()`
+
+Activates the given session.
+
+```dart
+Future activate(Session session)
+```
+
+**Example:**
+```dart
+final sessions = auth.client.sessions;
+if (sessions.length > 1) {
+ await auth.activate(sessions[1]); // Switch to another session
+}
+```
+
+---
+
+### `signOut()`
+
+Signs out of all sessions and deletes the current client.
+
+```dart
+Future signOut()
+```
+
+**Example:**
+```dart
+await auth.signOut();
+```
+
+---
+
+### `signOutOf()`
+
+Signs out of a specific session.
+
+```dart
+Future signOutOf(Session session)
+```
+
+**Example:**
+```dart
+await auth.signOutOf(auth.session!);
+```
+
+---
+
+### `transfer()`
+
+Transfers an OAuth authentication into a User (handles sign-in/sign-up transfer flow).
+
+```dart
+Future transfer()
+```
+
+**Example:**
+```dart
+// After OAuth or ID token authentication
+if (auth.signIn?.isTransferable == true) {
+ await auth.transfer(); // Switch to sign-up
+} else if (auth.signUp?.isTransferable == true) {
+ await auth.transfer(); // Switch to sign-in
+}
+```
+
+---
+
+## User Management
+
+### `updateUser()`
+
+Updates the current user's profile information.
+
+```dart
+Future updateUser({
+ String? username,
+ String? firstName,
+ String? lastName,
+ String? primaryEmailAddressId,
+ String? primaryPhoneNumberId,
+ String? primaryWeb3WalletId,
+ Map? metadata,
+ File? avatar,
+})
+```
+
+**Example:**
+```dart
+await auth.updateUser(
+ firstName: 'John',
+ lastName: 'Doe',
+ username: 'johndoe',
+ metadata: {'theme': 'dark'},
+);
+```
+
+---
+
+### `deleteUser()`
+
+Deletes the current user.
+
+```dart
+Future deleteUser()
+```
+
+**Example:**
+```dart
+if (auth.env.user.actions.deleteSelf) {
+ await auth.deleteUser();
+}
+```
+
+**Throws:**
+- `ClerkError` with code `cannotDeleteSelf` if user is not authorized to delete themselves
+
+---
+
+### `updateUserImage()`
+
+Updates the user's avatar.
+
+```dart
+Future updateUserImage(File file)
+```
+
+**Example:**
+```dart
+final imageFile = File('/path/to/avatar.jpg');
+await auth.updateUserImage(imageFile);
+```
+
+---
+
+### `deleteUserImage()`
+
+Deletes the user's avatar.
+
+```dart
+Future deleteUserImage()
+```
+
+**Example:**
+```dart
+await auth.deleteUserImage();
+```
+
+---
+
+### `addIdentifyingData()`
+
+Adds an email, phone number, or other identifier to the current user.
+
+```dart
+Future addIdentifyingData(
+ String identifier,
+ IdentifierType type,
+)
+```
+
+**Example:**
+```dart
+// Add email address
+await auth.addIdentifyingData(
+ 'newemail@example.com',
+ IdentifierType.emailAddress,
+);
+
+// Add phone number
+await auth.addIdentifyingData(
+ '+1234567890',
+ IdentifierType.phoneNumber,
+);
+```
+
+---
+
+### `verifyIdentifyingData()`
+
+Verifies user identifying data with a code.
+
+```dart
+Future verifyIdentifyingData(
+ UserIdentifyingData uid,
+ String code,
+)
+```
+
+**Example:**
+```dart
+final email = auth.user?.emailAddresses
+ ?.firstWhere((e) => e.emailAddress == 'newemail@example.com');
+if (email != null) {
+ await auth.verifyIdentifyingData(email, '123456');
+}
+```
+
+---
+
+### `deleteIdentifyingData()`
+
+Deletes user identifying data.
+
+```dart
+Future deleteIdentifyingData(
+ UserIdentifyingData uid,
+)
+```
+
+**Example:**
+```dart
+final email = auth.user?.emailAddresses?.first;
+if (email != null) {
+ await auth.deleteIdentifyingData(email);
+}
+```
+
+---
+
+## Password Management
+
+### `updateUserPassword()`
+
+Updates the current user's password.
+
+```dart
+Future updateUserPassword(
+ String currentPassword,
+ String newPassword, {
+ bool signOut = true,
+})
+```
+
+**Example:**
+```dart
+await auth.updateUserPassword(
+ 'OldPassword123!',
+ 'NewPassword456!',
+ signOut: false, // Keep user signed in
+);
+```
+
+---
+
+### `deleteUserPassword()`
+
+Deletes the current user's password.
+
+```dart
+Future deleteUserPassword(String currentPassword)
+```
+
+**Example:**
+```dart
+await auth.deleteUserPassword('CurrentPassword123!');
+```
+
+---
+
+## Organization Management
+
+### `createOrganization()`
+
+Creates a new organization.
+
+```dart
+Future createOrganization({
+ required String name,
+ String? slug,
+ File? logo,
+})
+```
+
+**Example:**
+```dart
+await auth.createOrganization(
+ name: 'Acme Corp',
+ slug: 'acme-corp',
+ logo: File('/path/to/logo.png'),
+);
+```
+
+---
+
+### `updateOrganization()`
+
+Updates an organization.
+
+```dart
+Future updateOrganization({
+ required Organization organization,
+ String? name,
+ File? logo,
+})
+```
+
+**Example:**
+```dart
+await auth.updateOrganization(
+ organization: auth.organization!,
+ name: 'New Name',
+ logo: File('/path/to/new-logo.png'),
+);
+```
+
+---
+
+### `setActiveOrganization()`
+
+Makes an organization active.
+
+```dart
+Future setActiveOrganization(Organization organization)
+```
+
+**Example:**
+```dart
+final orgs = auth.user?.organizationMemberships;
+if (orgs != null && orgs.isNotEmpty) {
+ await auth.setActiveOrganization(orgs.first.organization);
+}
+```
+
+---
+
+### `leaveOrganization()`
+
+Leaves an organization.
+
+```dart
+Future leaveOrganization({
+ required Organization organization,
+ Session? session,
+})
+```
+
+**Example:**
+```dart
+final success = await auth.leaveOrganization(
+ organization: auth.organization!,
+);
+```
+
+---
+
+### `fetchOrganizationInvitations()`
+
+Fetches all organization invitations for the user.
+
+```dart
+Future> fetchOrganizationInvitations()
+```
+
+**Example:**
+```dart
+final invitations = await auth.fetchOrganizationInvitations();
+for (final invitation in invitations) {
+ print('Invited to: ${invitation.organizationName}');
+}
+```
+
+---
+
+### `acceptOrganizationInvitation()`
+
+Accepts an organization invitation.
+
+```dart
+Future acceptOrganizationInvitation(
+ OrganizationInvitation invitation,
+)
+```
+
+**Example:**
+```dart
+final invitations = await auth.fetchOrganizationInvitations();
+if (invitations.isNotEmpty) {
+ await auth.acceptOrganizationInvitation(invitations.first);
+}
+```
+
+---
+
+### `fetchOrganizationDomains()`
+
+Fetches all domains for an organization.
+
+```dart
+Future> fetchOrganizationDomains({
+ required Organization organization,
+})
+```
+
+**Example:**
+```dart
+final domains = await auth.fetchOrganizationDomains(
+ organization: auth.organization!,
+);
+```
+
+---
+
+### `createDomain()`
+
+Creates a new domain within an organization.
+
+```dart
+Future createDomain({
+ required Organization organization,
+ required String name,
+ required EnrollmentMode mode,
+})
+```
+
+**Example:**
+```dart
+await auth.createDomain(
+ organization: auth.organization!,
+ name: 'example.com',
+ mode: EnrollmentMode.automaticInvitation,
+);
+```
+
+---
+
+## Advanced Methods
+
+### `refreshClient()`
+
+Refreshes the current client from the server.
+
+```dart
+Future refreshClient()
+```
+
+**Example:**
+```dart
+await auth.refreshClient();
+```
+
+---
+
+### `resetClient()`
+
+Resets the current client, clearing any SignUp or SignIn objects.
+
+```dart
+Future resetClient()
+```
+
+**Example:**
+```dart
+await auth.resetClient();
+```
+
+---
+
+### `refreshEnvironment()`
+
+Refreshes the current environment from the server.
+
+```dart
+Future refreshEnvironment()
+```
+
+**Example:**
+```dart
+await auth.refreshEnvironment();
+```
+
+---
+
+### `fetchApiResponse()`
+
+Low-level access to the Clerk API.
+
+```dart
+Future fetchApiResponse(
+ String url, {
+ HttpMethod method = HttpMethod.post,
+ Map? headers,
+ Map? params,
+ Map? nullableParams,
+ bool withSession = false,
+})
+```
+
+**Example:**
+```dart
+final response = await auth.fetchApiResponse(
+ '/users/me/custom_endpoint',
+ method: HttpMethod.get,
+ withSession: true,
+);
+```
+
+**Note:** This method will be deprecated in a future version. Use only for advanced use cases not covered by other methods.
+
+---
+
+## Error Handling
+
+All methods may throw `ClerkError` exceptions. Use try-catch blocks or override the `handleError` method to handle errors.
+
+**Example:**
+```dart
+try {
+ await auth.attemptSignIn(
+ strategy: Strategy.password,
+ identifier: 'user@example.com',
+ password: 'wrong_password',
+ );
+} on ClerkError catch (error) {
+ print('Error: ${error.message}');
+ print('Code: ${error.code}');
+}
+```
+
+**Custom Error Handling:**
+```dart
+class MyAuth extends Auth {
+ MyAuth({required super.config});
+
+ @override
+ void handleError(Object error) {
+ // Custom error handling
+ if (error is ClerkError) {
+ print('Clerk error: ${error.message}');
+ }
+ // Don't call super.handleError() to prevent throwing
+ }
+}
+```
+
+---
+
+## Common Patterns
+
+### Complete Sign-In Flow
+
+```dart
+// Email + Password with optional 2FA
+Future signInUser(String email, String password) async {
+ await auth.attemptSignIn(
+ strategy: Strategy.password,
+ identifier: email,
+ password: password,
+ );
+
+ // Check if 2FA is required
+ if (auth.signIn?.needsSecondFactor == true) {
+ // Prompt user for 2FA code
+ final code = await promptUserFor2FACode();
+ await auth.attemptSignIn(
+ strategy: Strategy.emailCode,
+ code: code,
+ );
+ }
+
+ // User is now signed in
+ print('Welcome, ${auth.user?.fullName}!');
+}
+```
+
+### Complete Sign-Up Flow
+
+```dart
+// Email + Password sign-up with verification
+Future signUpUser({
+ required String email,
+ required String password,
+ required String firstName,
+ required String lastName,
+}) async {
+ // Step 1: Create sign-up
+ await auth.attemptSignUp(
+ strategy: Strategy.emailCode,
+ emailAddress: email,
+ password: password,
+ passwordConfirmation: password,
+ firstName: firstName,
+ lastName: lastName,
+ );
+
+ // Step 2: Verify email
+ final code = await promptUserForEmailCode();
+ await auth.attemptSignUp(
+ strategy: Strategy.emailCode,
+ code: code,
+ );
+
+ // User is now signed up and signed in
+ print('Welcome, ${auth.user?.fullName}!');
+}
+```
+
+### OAuth Sign-In with Transfer
+
+```dart
+// Apple Sign In with automatic transfer
+Future appleSignIn(String idToken, {String? firstName, String? lastName}) async {
+ // Try sign-in first
+ await auth.idTokenSignIn(
+ provider: IdTokenProvider.apple,
+ idToken: idToken,
+ );
+
+ // If user doesn't exist, transfer to sign-up
+ if (auth.signIn?.isTransferable == true) {
+ await auth.transfer();
+
+ // Update with additional info if available
+ if (firstName != null || lastName != null) {
+ await auth.attemptSignUp(
+ strategy: Strategy.oauthTokenApple,
+ firstName: firstName,
+ lastName: lastName,
+ );
+ }
+ }
+
+ print('Signed in: ${auth.user?.fullName}');
+}
+```
+
+### Multi-Session Management
+
+```dart
+// Switch between multiple sessions
+Future switchSession(int sessionIndex) async {
+ final sessions = auth.client.sessions;
+ if (sessionIndex < sessions.length) {
+ await auth.activate(sessions[sessionIndex]);
+ print('Switched to: ${auth.user?.fullName}');
+ }
+}
+
+// Sign out of specific session
+Future signOutSession(Session session) async {
+ await auth.signOutOf(session);
+ print('Signed out of session: ${session.id}');
+}
+```
+
+---
+
+## Best Practices
+
+1. **Always initialize before use**: Call `initialize()` before any other Auth methods
+2. **Handle errors gracefully**: Wrap Auth calls in try-catch blocks or override `handleError()`
+3. **Use re-entrant methods correctly**: `attemptSignIn()` and `attemptSignUp()` are designed to be called multiple times
+4. **Check transfer status**: After OAuth/ID token auth, check `isTransferable` and call `transfer()` if needed
+5. **Clean up resources**: Call `terminate()` when disposing of the Auth object
+6. **Monitor session tokens**: Use `sessionTokenStream` to keep your API client updated with fresh tokens
+7. **Validate passwords**: Ensure password and passwordConfirmation match before calling `attemptSignUp()`
+8. **Check environment settings**: Use `env` to check what features are enabled before attempting operations
+
+---
+
+## Related Documentation
+
+- [Clerk Dashboard](https://dashboard.clerk.com/)
+- [Clerk API Reference](https://clerk.com/docs/reference/backend-api)
+- [Flutter SDK Guide](https://clerk.com/docs/quickstarts/flutter)
+
+---
+
+*Generated for clerk_auth version 0.0.14-beta*
+
+
diff --git a/docs/clerk_auth/auth_config.md b/docs/clerk_auth/auth_config.md
new file mode 100644
index 00000000..9a466c29
--- /dev/null
+++ b/docs/clerk_auth/auth_config.md
@@ -0,0 +1,520 @@
+# AuthConfig Documentation
+
+This document provides comprehensive documentation for the `AuthConfig` class from `clerk_auth/lib/src/clerk_auth/auth_config.dart`.
+
+## Overview
+
+The `AuthConfig` class holds all configurable items required for the `Auth` class, with sensible defaults. It is the primary configuration object for initializing Clerk authentication in your application.
+
+## Class Definition
+
+```dart
+class AuthConfig {
+ const AuthConfig({
+ required this.publishableKey,
+ required this.persistor,
+ this.flags = const SdkFlags(),
+ this.sessionTokenPolling = true,
+ this.retryOptions = const RetryOptions(),
+ this.defaultSessionTokenTemplate,
+ LocalesLookup? localesLookup,
+ bool? isTestMode,
+ String? telemetryEndpoint,
+ Duration? telemetryPeriod,
+ Duration? clientRefreshPeriod,
+ Duration? httpConnectionTimeout,
+ HttpService? httpService,
+ });
+}
+```
+
+---
+
+## Required Parameters
+
+### `publishableKey`
+
+**Type:** `String`
+
+The publishable key from your Clerk dashboard that identifies your auth service account.
+
+**Example:**
+```dart
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+);
+```
+
+**Where to find it:**
+1. Go to [Clerk Dashboard](https://dashboard.clerk.com/)
+2. Select your application
+3. Navigate to API Keys
+4. Copy the "Publishable Key"
+
+---
+
+### `persistor`
+
+**Type:** `Persistor`
+
+The persistor used for storing authentication state between app sessions.
+
+**Example:**
+```dart
+// Using DefaultPersistor
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: DefaultPersistor(
+ getCacheDirectory: () => getApplicationDocumentsDirectory(),
+ ),
+);
+
+// Using no persistence (testing only)
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: Persistor.none,
+);
+```
+
+**See also:** [Persistor Documentation](persistor.md)
+
+---
+
+## Optional Parameters
+
+### `flags`
+
+**Type:** `SdkFlags`
+**Default:** `const SdkFlags()`
+
+Flags used to affect SDK behavior. Extended by `clerk_flutter` for Flutter-specific flags.
+
+**Example:**
+```dart
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ flags: const SdkFlags(),
+);
+```
+
+---
+
+### `sessionTokenPolling`
+
+**Type:** `bool`
+**Default:** `true`
+
+Whether to regularly poll for new session tokens. When enabled, the SDK automatically refreshes session tokens before they expire.
+
+**Example:**
+```dart
+// Enable automatic token refresh (default)
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ sessionTokenPolling: true,
+);
+
+// Disable automatic token refresh
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ sessionTokenPolling: false,
+);
+```
+
+**When to disable:**
+- Testing scenarios where you want manual control
+- Applications that don't need long-lived sessions
+
+---
+
+### `retryOptions`
+
+**Type:** `RetryOptions`
+**Default:** `const RetryOptions()`
+
+Options for retrying failed HTTP requests. Uses the `retry` package.
+
+**Example:**
+```dart
+import 'package:retry/retry.dart';
+
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ retryOptions: RetryOptions(
+ maxAttempts: 5,
+ delayFactor: Duration(milliseconds: 200),
+ maxDelay: Duration(seconds: 10),
+ ),
+);
+```
+
+**RetryOptions properties:**
+- `maxAttempts`: Maximum number of retry attempts (default: 8)
+- `delayFactor`: Initial delay between retries (default: 200ms)
+- `maxDelay`: Maximum delay between retries (default: 30s)
+- `randomizationFactor`: Randomization factor for delays (default: 0.25)
+
+---
+
+### `defaultSessionTokenTemplate`
+
+**Type:** `String?`
+**Default:** `null`
+
+Default template name for session token retrieval. Useful when using custom JWT templates.
+
+**Example:**
+```dart
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ defaultSessionTokenTemplate: 'my_custom_template',
+);
+```
+
+**Use case:**
+When you have custom claims or need specific JWT structure for your backend API.
+
+---
+
+### `localesLookup`
+
+**Type:** `LocalesLookup` (function: `List Function()`)
+**Default:** `Auth.defaultLocalesLookup` (returns `['en']`)
+
+Function to return the current user's locale preferences for translations.
+
+**Example:**
+```dart
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ localesLookup: () {
+ // Return user's preferred locales
+ return ['es', 'en']; // Spanish first, English fallback
+ },
+);
+```
+
+---
+
+### `isTestMode`
+
+**Type:** `bool`
+**Default:** `false`
+
+Whether the SDK is running in test mode.
+
+**Example:**
+```dart
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ isTestMode: true,
+);
+```
+
+---
+
+### `telemetryEndpoint`
+
+**Type:** `String`
+**Default:** `'https://clerk-telemetry.com/v1/event'`
+
+The endpoint to send telemetry data to.
+
+**Example:**
+```dart
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ telemetryEndpoint: 'https://my-custom-telemetry.com/events',
+);
+```
+
+---
+
+### `telemetryPeriod`
+
+**Type:** `Duration`
+**Default:** `Duration(milliseconds: 29300)` (~30 seconds)
+
+The duration between sends of telemetry data. Set to `Duration.zero` to disable telemetry.
+
+**Example:**
+```dart
+// Custom telemetry interval
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ telemetryPeriod: Duration(minutes: 1),
+);
+
+// Disable telemetry
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ telemetryPeriod: Duration.zero,
+);
+```
+
+**Note:** The default is slightly offset from 30s to avoid repeated clashes with other regular tasks.
+
+---
+
+### `clientRefreshPeriod`
+
+**Type:** `Duration`
+**Default:** `Duration(milliseconds: 9700)` (~10 seconds)
+
+The duration between calls to refresh the client object. Set to `Duration.zero` to disable automatic client refresh.
+
+**Example:**
+```dart
+// Custom refresh interval
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ clientRefreshPeriod: Duration(seconds: 30),
+);
+
+// Disable automatic refresh
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ clientRefreshPeriod: Duration.zero,
+);
+```
+
+**Note:** The default is slightly offset from 10s to avoid repeated clashes with other regular tasks.
+
+**When to adjust:**
+- Increase for battery-sensitive applications
+- Decrease for applications requiring real-time updates
+- Disable for complete manual control
+
+---
+
+### `httpConnectionTimeout`
+
+**Type:** `Duration`
+**Default:** `Duration(milliseconds: 500)`
+
+The duration to wait for HTTP connectivity before timing out in a connectivity test.
+
+**Example:**
+```dart
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ httpConnectionTimeout: Duration(seconds: 2),
+);
+```
+
+---
+
+### `httpService`
+
+**Type:** `HttpService`
+**Default:** `DefaultHttpService()`
+
+The HTTP service used to communicate with the Clerk backend.
+
+**Example:**
+```dart
+// Using default HTTP service
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ httpService: DefaultHttpService(),
+);
+
+// Using custom HTTP service
+class MyHttpService implements HttpService {
+ // ... implement interface
+}
+
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ httpService: MyHttpService(),
+);
+```
+
+**See also:** [HttpService Documentation](http_service.md)
+
+---
+
+## Methods
+
+### `initialize()`
+
+Initializes the configuration by initializing the persistor and HTTP service.
+
+```dart
+Future initialize()
+```
+
+**Example:**
+```dart
+final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+);
+await config.initialize();
+```
+
+**Note:** This is typically called automatically by `Auth.initialize()`.
+
+---
+
+### `terminate()`
+
+Terminates the configuration by terminating the HTTP service and persistor.
+
+```dart
+void terminate()
+```
+
+**Example:**
+```dart
+config.terminate();
+```
+
+**Note:** This is typically called automatically by `Auth.terminate()`.
+
+---
+
+## Complete Examples
+
+### Basic Configuration
+
+```dart
+import 'package:clerk_auth/clerk_auth.dart';
+import 'package:path_provider/path_provider.dart';
+
+Future createBasicConfig() async {
+ return AuthConfig(
+ publishableKey: 'pk_test_Y2xlcmsuZXhhbXBsZS5jb20k',
+ persistor: DefaultPersistor(
+ getCacheDirectory: getApplicationDocumentsDirectory,
+ ),
+ );
+}
+```
+
+### Production Configuration
+
+```dart
+import 'package:clerk_auth/clerk_auth.dart';
+import 'package:path_provider/path_provider.dart';
+import 'package:retry/retry.dart';
+
+Future createProductionConfig() async {
+ return AuthConfig(
+ publishableKey: 'pk_live_...',
+ persistor: DefaultPersistor(
+ getCacheDirectory: getApplicationDocumentsDirectory,
+ ),
+ sessionTokenPolling: true,
+ retryOptions: RetryOptions(
+ maxAttempts: 5,
+ delayFactor: Duration(milliseconds: 200),
+ ),
+ clientRefreshPeriod: Duration(seconds: 15),
+ telemetryPeriod: Duration(seconds: 60),
+ );
+}
+```
+
+### Testing Configuration
+
+```dart
+import 'package:clerk_auth/clerk_auth.dart';
+
+AuthConfig createTestConfig() {
+ return AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: Persistor.none, // No persistence in tests
+ isTestMode: true,
+ sessionTokenPolling: false,
+ clientRefreshPeriod: Duration.zero,
+ telemetryPeriod: Duration.zero,
+ );
+}
+```
+
+### Custom Locale Configuration
+
+```dart
+import 'package:clerk_auth/clerk_auth.dart';
+import 'package:flutter/material.dart';
+
+AuthConfig createLocalizedConfig(BuildContext context) {
+ return AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ localesLookup: () {
+ final locale = Localizations.localeOf(context);
+ return [locale.languageCode, 'en']; // User's locale + English fallback
+ },
+ );
+}
+```
+
+### Performance-Optimized Configuration
+
+```dart
+import 'package:clerk_auth/clerk_auth.dart';
+
+AuthConfig createOptimizedConfig() {
+ return AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: myPersistor,
+ // Reduce polling frequency for battery savings
+ clientRefreshPeriod: Duration(seconds: 30),
+ telemetryPeriod: Duration(minutes: 5),
+ // Faster timeout for better UX
+ httpConnectionTimeout: Duration(milliseconds: 300),
+ );
+}
+```
+
+---
+
+## Best Practices
+
+1. **Always use a Persistor in production**: Use `DefaultPersistor` or a custom implementation. Only use `Persistor.none` for testing.
+
+2. **Secure your publishable key**: Store it in environment variables or secure configuration, not hardcoded in source.
+
+3. **Adjust polling based on use case**:
+ - Real-time apps: Shorter `clientRefreshPeriod`
+ - Battery-sensitive apps: Longer periods or disable polling
+ - Background apps: Disable polling and refresh manually
+
+4. **Configure retry options for reliability**: Adjust based on your network conditions and user experience requirements.
+
+5. **Use custom session token templates**: When you need specific JWT claims for your backend API.
+
+6. **Disable telemetry in development**: Set `telemetryPeriod` to `Duration.zero` during development if desired.
+
+7. **Test with different configurations**: Create separate configs for development, staging, and production.
+
+---
+
+## Related Documentation
+
+- [Auth Documentation](auth.md)
+- [Persistor Documentation](persistor.md)
+- [HttpService Documentation](http_service.md)
+- [Clerk Dashboard](https://dashboard.clerk.com/)
+
+---
+
+*Generated for clerk_auth version 0.0.14-beta*
diff --git a/docs/clerk_auth/http_service.md b/docs/clerk_auth/http_service.md
new file mode 100644
index 00000000..b6785e44
--- /dev/null
+++ b/docs/clerk_auth/http_service.md
@@ -0,0 +1,657 @@
+# HttpService Documentation
+
+This document provides comprehensive documentation for the `HttpService` interface and its implementations from `clerk_auth/lib/src/clerk_auth/http_service.dart`.
+
+## Overview
+
+The `HttpService` abstract interface defines how the Clerk SDK communicates with the Clerk backend over HTTP. It provides methods for sending requests, uploading files, and checking connectivity.
+
+## HttpMethod Enum
+
+```dart
+enum HttpMethod {
+ delete,
+ get,
+ patch,
+ post,
+ put,
+}
+```
+
+**Methods:**
+- `delete`: HTTP DELETE
+- `get`: HTTP GET
+- `patch`: HTTP PATCH
+- `post`: HTTP POST
+- `put`: HTTP PUT
+
+**Properties:**
+- `isGet`: Returns `true` if method is GET
+- `isNotGet`: Returns `true` if method is not GET
+- `toString()`: Returns uppercase method name (e.g., "GET", "POST")
+
+**Example:**
+```dart
+final method = HttpMethod.post;
+print(method.toString()); // "POST"
+print(method.isGet); // false
+print(method.isNotGet); // true
+```
+
+---
+
+## Abstract Interface
+
+```dart
+abstract interface class HttpService {
+ const HttpService();
+
+ Future initialize();
+ void terminate();
+ Future ping(Uri uri, {required Duration timeout});
+ Future send(
+ HttpMethod method,
+ Uri uri, {
+ Map? headers,
+ Map? params,
+ String? body,
+ });
+ Future sendByteStream(
+ HttpMethod method,
+ Uri uri,
+ http.ByteStream byteStream,
+ int length,
+ Map headers,
+ );
+}
+```
+
+---
+
+## Methods
+
+### `initialize()`
+
+Initializes the HTTP service. May be called multiple times and must handle that gracefully.
+
+```dart
+Future initialize()
+```
+
+**Example:**
+```dart
+final httpService = DefaultHttpService();
+await httpService.initialize();
+```
+
+**Note:** The default implementation is a no-op.
+
+---
+
+### `terminate()`
+
+Terminates the HTTP service and cleans up resources. May be called multiple times and must handle that gracefully.
+
+```dart
+void terminate()
+```
+
+**Example:**
+```dart
+httpService.terminate();
+```
+
+---
+
+### `ping()`
+
+Checks that connectivity to an endpoint is available.
+
+```dart
+Future ping(Uri uri, {required Duration timeout})
+```
+
+**Parameters:**
+- `uri`: The endpoint to ping
+- `timeout`: Maximum time to wait for response
+
+**Returns:**
+- `true` if endpoint is reachable and returns 200 status
+- `false` otherwise
+
+**Example:**
+```dart
+final isReachable = await httpService.ping(
+ Uri.parse('https://api.clerk.com'),
+ timeout: Duration(seconds: 5),
+);
+if (isReachable) {
+ print('API is reachable');
+}
+```
+
+---
+
+### `send()`
+
+Sends an HTTP request to the backend and receives a response.
+
+```dart
+Future send(
+ HttpMethod method,
+ Uri uri, {
+ Map? headers,
+ Map? params,
+ String? body,
+})
+```
+
+**Parameters:**
+- `method`: The HTTP method to use
+- `uri`: The endpoint URI
+- `headers`: Optional HTTP headers
+- `params`: Optional form parameters (converted to body fields)
+- `body`: Optional request body (raw string)
+
+**Returns:**
+- `http.Response` from the server
+
+**Example:**
+```dart
+final response = await httpService.send(
+ HttpMethod.post,
+ Uri.parse('https://api.clerk.com/v1/client'),
+ headers: {
+ 'Authorization': 'Bearer token',
+ 'Content-Type': 'application/json',
+ },
+ body: jsonEncode({'key': 'value'}),
+);
+
+print('Status: ${response.statusCode}');
+print('Body: ${response.body}');
+```
+
+**With params:**
+```dart
+final response = await httpService.send(
+ HttpMethod.post,
+ Uri.parse('https://api.clerk.com/v1/sign_in'),
+ params: {
+ 'identifier': 'user@example.com',
+ 'password': 'password123',
+ },
+);
+```
+
+---
+
+### `sendByteStream()`
+
+Uploads a file to the backend using a multipart request.
+
+```dart
+Future sendByteStream(
+ HttpMethod method,
+ Uri uri,
+ http.ByteStream byteStream,
+ int length,
+ Map headers,
+)
+```
+
+**Parameters:**
+- `method`: The HTTP method to use
+- `uri`: The endpoint URI
+- `byteStream`: The file data as a byte stream
+- `length`: The length of the byte stream
+- `headers`: HTTP headers
+
+**Returns:**
+- `http.Response` from the server
+
+**Example:**
+```dart
+import 'dart:io';
+import 'package:http/http.dart' as http;
+
+final file = File('/path/to/avatar.jpg');
+final byteStream = http.ByteStream(file.openRead());
+final length = await file.length();
+
+final response = await httpService.sendByteStream(
+ HttpMethod.post,
+ Uri.parse('https://api.clerk.com/v1/me/profile_image'),
+ byteStream,
+ length,
+ {
+ 'Authorization': 'Bearer token',
+ },
+);
+```
+
+---
+
+## DefaultHttpService
+
+The default implementation of `HttpService` using the `http` package.
+
+### Constructor
+
+```dart
+const DefaultHttpService()
+```
+
+**Example:**
+```dart
+final httpService = DefaultHttpService();
+```
+
+### Behavior
+
+- Uses a single `http.Client` instance per `DefaultHttpService` instance
+- Automatically manages client lifecycle
+- Cleans up client on `terminate()`
+- Thread-safe client management
+
+### Implementation Details
+
+**Client Management:**
+```dart
+static final _clients = {};
+http.Client get _client => _clients[this] ??= http.Client();
+```
+
+**Ping Implementation:**
+- Uses HTTP HEAD request
+- Returns `true` only if status code is 200
+- Catches all exceptions and returns `false`
+
+**Send Implementation:**
+- Creates `http.Request` with method and URI
+- Adds headers if provided
+- Converts params to body fields if provided
+- Sets body if provided
+- Sends request and converts streamed response to regular response
+
+**SendByteStream Implementation:**
+- Creates `http.MultipartRequest`
+- Adds file as multipart file with field name "file"
+- Uses hash code as filename
+- Sends request and converts streamed response
+
+---
+
+## Custom Implementation
+
+You can create custom HTTP service implementations for specific requirements.
+
+### Example: Logging HTTP Service
+
+```dart
+class LoggingHttpService implements HttpService {
+ final HttpService _delegate;
+
+ LoggingHttpService(this._delegate);
+
+ @override
+ Future initialize() => _delegate.initialize();
+
+ @override
+ void terminate() => _delegate.terminate();
+
+ @override
+ Future ping(Uri uri, {required Duration timeout}) async {
+ print('Pinging: $uri');
+ final result = await _delegate.ping(uri, timeout: timeout);
+ print('Ping result: $result');
+ return result;
+ }
+
+ @override
+ Future send(
+ HttpMethod method,
+ Uri uri, {
+ Map? headers,
+ Map? params,
+ String? body,
+ }) async {
+ print('Sending $method to $uri');
+ final response = await _delegate.send(
+ method,
+ uri,
+ headers: headers,
+ params: params,
+ body: body,
+ );
+ print('Response: ${response.statusCode}');
+ return response;
+ }
+
+ @override
+ Future sendByteStream(
+ HttpMethod method,
+ Uri uri,
+ http.ByteStream byteStream,
+ int length,
+ Map headers,
+ ) async {
+ print('Uploading file to $uri (${length} bytes)');
+ final response = await _delegate.sendByteStream(
+ method,
+ uri,
+ byteStream,
+ length,
+ headers,
+ );
+ print('Upload response: ${response.statusCode}');
+ return response;
+ }
+}
+```
+
+### Example: Retry HTTP Service
+
+```dart
+import 'package:retry/retry.dart';
+
+class RetryHttpService implements HttpService {
+ final HttpService _delegate;
+ final RetryOptions _retryOptions;
+
+ RetryHttpService(this._delegate, {
+ RetryOptions? retryOptions,
+ }) : _retryOptions = retryOptions ?? const RetryOptions();
+
+ @override
+ Future initialize() => _delegate.initialize();
+
+ @override
+ void terminate() => _delegate.terminate();
+
+ @override
+ Future ping(Uri uri, {required Duration timeout}) {
+ return _delegate.ping(uri, timeout: timeout);
+ }
+
+ @override
+ Future send(
+ HttpMethod method,
+ Uri uri, {
+ Map? headers,
+ Map? params,
+ String? body,
+ }) async {
+ return _retryOptions.retry(
+ () => _delegate.send(
+ method,
+ uri,
+ headers: headers,
+ params: params,
+ body: body,
+ ),
+ retryIf: (e) => e is SocketException || e is TimeoutException,
+ );
+ }
+
+ @override
+ Future sendByteStream(
+ HttpMethod method,
+ Uri uri,
+ http.ByteStream byteStream,
+ int length,
+ Map headers,
+ ) async {
+ return _retryOptions.retry(
+ () => _delegate.sendByteStream(
+ method,
+ uri,
+ byteStream,
+ length,
+ headers,
+ ),
+ retryIf: (e) => e is SocketException || e is TimeoutException,
+ );
+ }
+}
+```
+
+### Example: Mock HTTP Service (Testing)
+
+```dart
+class MockHttpService implements HttpService {
+ final Map _mockResponses = {};
+ bool _initialized = false;
+
+ void addMockResponse(String key, http.Response response) {
+ _mockResponses[key] = response;
+ }
+
+ @override
+ Future initialize() async {
+ _initialized = true;
+ }
+
+ @override
+ void terminate() {
+ _initialized = false;
+ _mockResponses.clear();
+ }
+
+ @override
+ Future ping(Uri uri, {required Duration timeout}) async {
+ return true; // Always return true in tests
+ }
+
+ @override
+ Future send(
+ HttpMethod method,
+ Uri uri, {
+ Map? headers,
+ Map? params,
+ String? body,
+ }) async {
+ final key = '${method}_${uri.path}';
+ if (_mockResponses.containsKey(key)) {
+ return _mockResponses[key]!;
+ }
+ return http.Response('{}', 200);
+ }
+
+ @override
+ Future sendByteStream(
+ HttpMethod method,
+ Uri uri,
+ http.ByteStream byteStream,
+ int length,
+ Map headers,
+ ) async {
+ return http.Response('{"uploaded": true}', 200);
+ }
+}
+```
+
+---
+
+## Complete Examples
+
+### Basic Usage
+
+```dart
+import 'package:clerk_auth/clerk_auth.dart';
+
+void main() async {
+ final httpService = DefaultHttpService();
+ await httpService.initialize();
+
+ final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: Persistor.none,
+ httpService: httpService,
+ );
+
+ final auth = Auth(config: config);
+ await auth.initialize();
+
+ // Use auth...
+
+ auth.terminate();
+ httpService.terminate();
+}
+```
+
+### With Logging
+
+```dart
+import 'package:clerk_auth/clerk_auth.dart';
+
+void main() async {
+ final baseService = DefaultHttpService();
+ final loggingService = LoggingHttpService(baseService);
+ await loggingService.initialize();
+
+ final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: Persistor.none,
+ httpService: loggingService,
+ );
+
+ final auth = Auth(config: config);
+ await auth.initialize();
+
+ // All HTTP requests will be logged
+}
+```
+
+### Testing Setup
+
+```dart
+import 'package:clerk_auth/clerk_auth.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:http/http.dart' as http;
+
+void main() {
+ test('auth test with mock HTTP', () async {
+ final mockHttp = MockHttpService();
+ mockHttp.addMockResponse(
+ 'POST_/v1/client',
+ http.Response('{"client": {}}', 200),
+ );
+
+ final config = AuthConfig(
+ publishableKey: 'pk_test_...',
+ persistor: Persistor.none,
+ httpService: mockHttp,
+ );
+
+ final auth = Auth(config: config);
+ await auth.initialize();
+
+ // Test with mocked responses
+ });
+}
+```
+
+---
+
+## Best Practices
+
+1. **Use DefaultHttpService for most cases**: It's well-tested and handles common scenarios.
+
+2. **Implement custom services for specific needs**:
+ - Logging/debugging
+ - Custom retry logic
+ - Request/response transformation
+ - Testing with mocks
+
+3. **Handle initialization properly**:
+ - Always call `initialize()` before use
+ - Handle multiple initialization calls gracefully
+ - Clean up in `terminate()`
+
+4. **Manage client lifecycle**:
+ - Create clients in `initialize()`
+ - Close clients in `terminate()`
+ - Reuse clients when possible
+
+5. **Error handling**:
+ - Catch and handle network exceptions
+ - Implement retry logic for transient failures
+ - Log errors for debugging
+
+6. **Testing**:
+ - Use mock implementations in tests
+ - Test error scenarios
+ - Verify request/response handling
+
+7. **Performance**:
+ - Reuse HTTP clients
+ - Implement connection pooling
+ - Set appropriate timeouts
+
+---
+
+## Troubleshooting
+
+### Connection Timeouts
+
+**Problem:** Requests timeout frequently.
+
+**Solutions:**
+- Increase `httpConnectionTimeout` in `AuthConfig`
+- Check network connectivity
+- Verify API endpoint is reachable
+- Implement retry logic
+
+### SSL/TLS Errors
+
+**Problem:** Certificate verification failures.
+
+**Solutions:**
+- Ensure system certificates are up to date
+- Check for man-in-the-middle proxies
+- Verify API endpoint uses valid certificate
+- Don't disable certificate validation in production
+
+### Memory Leaks
+
+**Problem:** HTTP clients not being cleaned up.
+
+**Solutions:**
+- Always call `terminate()` when done
+- Ensure clients are closed properly
+- Use `DefaultHttpService` which manages lifecycle
+- Profile memory usage
+
+### Request Failures
+
+**Problem:** Requests fail with various errors.
+
+**Solutions:**
+- Check request parameters and headers
+- Verify API endpoint and method
+- Implement logging to debug requests
+- Use retry logic for transient failures
+
+---
+
+## Related Documentation
+
+- [AuthConfig Documentation](auth_config.md)
+- [Auth Documentation](auth.md)
+- [Persistor Documentation](persistor.md)
+
+---
+
+## Additional Resources
+
+- [http package](https://pub.dev/packages/http)
+- [retry package](https://pub.dev/packages/retry)
+- [Clerk API Reference](https://clerk.com/docs/reference/backend-api)
+
+---
+
+*Generated for clerk_auth version 0.0.14-beta*
+
+
+
diff --git a/docs/clerk_auth/persistor.md b/docs/clerk_auth/persistor.md
new file mode 100644
index 00000000..0dc5a373
--- /dev/null
+++ b/docs/clerk_auth/persistor.md
@@ -0,0 +1,539 @@
+# Persistor Documentation
+
+This document provides comprehensive documentation for the `Persistor` abstract class and its implementations from `clerk_auth/lib/src/clerk_auth/persistor.dart`.
+
+## Overview
+
+The `Persistor` abstract class defines the persistence interface for storing authentication state between app sessions. It allows the Clerk SDK to maintain user sessions across app restarts.
+
+## Abstract Class
+
+```dart
+abstract class Persistor {
+ Future initialize();
+ void terminate();
+ FutureOr read(String key);
+ FutureOr write(String key, T value);
+ FutureOr delete(String key);
+}
+```
+
+---
+
+## Methods
+
+### `initialize()`
+
+Initializes the persistor service. Called once when the Auth object is initialized.
+
+```dart
+Future initialize()
+```
+
+**Example:**
+```dart
+final persistor = DefaultPersistor(
+ getCacheDirectory: getApplicationDocumentsDirectory,
+);
+await persistor.initialize();
+```
+
+---
+
+### `terminate()`
+
+Terminates the persistor service. Called when the Auth object is terminated.
+
+```dart
+void terminate()
+```
+
+**Example:**
+```dart
+persistor.terminate();
+```
+
+---
+
+### `read()`
+
+Reads a value from storage by key.
+
+```dart
+FutureOr read(String key)
+```
+
+**Parameters:**
+- `key`: The storage key to read from
+
+**Returns:**
+- The stored value of type `T`, or `null` if not found
+
+**Example:**
+```dart
+final clientData = await persistor.read