SDK Usage
The OpenFeature Provider IntelliToggle SDK is the canonical Dart server integration for IntelliToggle.
It integrates with OpenFeature Dart SDK and supports targeting, rule-based rollouts, and experimentation workflows.
1. Prerequisites
|
Dart language version >= |
-
An IntelliToggle account with OAuth2 client credentials for the target project and environment
-
Familiarity with feature flags
-
The environment bundle from Third-Party Integration Checklist
2. Installation
Add the OpenFeature Dart SDK and IntelliToggle provider to your project:
pubspec.yaml
dependencies:
openfeature_dart_server_sdk: ^0.0.22
openfeature_provider_intellitoggle: ^0.0.10
Then run:
dart pub get
3. Initialization
Before evaluating flags, configure the OpenFeature SDK with the IntelliToggle provider.
Initialize the provider once when your service starts. Do not create a new provider for every request.
import 'dart:io';
import 'package:openfeature_provider_intellitoggle/openfeature_provider_intellitoggle.dart';
void main() async {
final provider = IntelliToggleProvider(
clientId: Platform.environment['INTELLITOGGLE_CLIENT_ID']!,
clientSecret: Platform.environment['INTELLITOGGLE_CLIENT_SECRET']!,
tenantId: Platform.environment['INTELLITOGGLE_TENANT_ID']!,
options: IntelliToggleOptions.production(
baseUri: Uri.parse(
Platform.environment['INTELLITOGGLE_API_URL'] ??
'https://api.intellitoggle.com',
),
timeout: const Duration(seconds: 10),
pollingInterval: const Duration(minutes: 5),
),
);
await provider.initialize();
final api = OpenFeatureAPI();
await api.setProvider(provider);
final clientMetadata = ClientMetadata(name: 'my-client', version: '0.0.1');
final hookManager = HookManager();
final defaultEvalContext = EvaluationContext(attributes: {});
final featureClient = FeatureClient(
metadata: clientMetadata,
provider: provider,
hookManager: hookManager,
defaultContext: defaultEvalContext,
);
final client = IntelliToggleClient(featureClient);
final newFeatureEnabled = await client.getBooleanValue(
'dark-mode',
false,
targetingKey: 'user-123',
evaluationContext: {
'role': 'admin',
'plan': 'enterprise',
'region': 'us-east',
},
);
print('Flag value: $newFeatureEnabled');
await provider.shutdown();
}
4. Basic Usage
Once the provider is initialized and registered globally, flag evaluation is straightforward.
Minimal evaluation:
final enabled = await client.getBooleanValue('new-api-endpoint', false);
For service-level gates, use a stable service targeting key:
final enabled = await client.getBooleanValue(
'service-runtime-enabled',
false,
targetingKey: 'billing-api-prod',
evaluationContext: {
'service': 'billing-api',
'environment': Platform.environment['INTELLITOGGLE_ENVIRONMENT'] ??
'production',
},
);
Flag evaluation with targeting and context:
final enabled = await client.getBooleanValue(
'new-api-endpoint',
false,
targetingKey: 'user-123',
evaluationContext: {
'role': 'admin',
'plan': 'enterprise',
'region': 'us-east',
},
);
print('Feature enabled: $enabled');
5. Flutter mobile offline mode
The Flutter client SDK includes local flag caching for mobile applications. Offline mode is enabled by default so a device can continue evaluating the last known flag values when the IntelliToggle API is temporarily unavailable.
Do not embed tenant-wide client secrets in a mobile app. Mobile apps should receive a short-lived, scoped token from your backend or another controlled token broker, then pass that value as the SDK apiKey.
|
import 'package:intellitoggle_flutter_sdk/flutter.dart';
final intelliToggle = IntelliToggle();
await intelliToggle.initialize(
apiUrl: 'https://api.intellitoggle.com',
environment: 'production',
apiKey: scopedMobileToken,
offlineMode: true,
enableStreaming: true,
globalContext: {
'userId': currentUser.id,
'plan': currentUser.plan,
},
);
final enabled = await intelliToggle.getBooleanFlag(
'new-mobile-home',
defaultValue: false,
context: {
'platform': 'android',
'appVersion': '1.4.0',
},
);
Offline behavior:
-
Successful online evaluations are cached locally with Hive.
-
The cache key includes the flag key and environment. If
userIdis present in the evaluation context, it is also included so user-specific flags do not share values across users. -
Cached values use the TTL returned by the API when present; otherwise the SDK records the default 24-hour TTL.
-
If an API call, timeout, or network request fails and
offlineModeistrue, the SDK returns the compatible cached value. -
If no compatible cached value exists, the SDK returns the default value supplied by the caller.
-
Cached values should be treated as last-known-good values. Keep application defaults safe for critical paths and call
clearCache()after logout, tenant switches, or user switches.
await intelliToggle.clearCache();
6. Advanced Usage
Beyond simple flag checks, the IntelliToggle provider supports richer evaluation contexts and provider lifecycle events.
6.1. Contextual Evaluation
Pass a targeting key and additional attributes when resolving flags:
final enabled = await client.getBooleanValue(
'new-api-endpoint',
false,
targetingKey: 'user-123',
evaluationContext: {
'role': 'admin',
'plan': 'enterprise',
'region': 'us-east',
},
);
6.2. Multi-Context Evaluation
Evaluate flags against multiple entities, such as a user and an organization:
final multiContext = client.createMultiContext({
'user': {
'targetingKey': 'user-123',
'role': 'admin',
'plan': 'enterprise',
},
'organization': {
'targetingKey': 'org-456',
'tier': 'premium',
'industry': 'fintech',
},
});
final config = await client.getObjectValue(
'feature-config',
{},
evaluationContext: multiContext.attributes,
);
6.3. Custom Context Types
Define your own context kinds, such as device or service:
final deviceContext = client.createContext(
targetingKey: 'device-789',
kind: 'device',
customAttributes: {
'os': 'linux',
'version': '5.4.0',
'datacenter': 'us-west-2',
},
);
final threshold = await client.getIntegerValue(
'rate-limit',
1000,
evaluationContext: deviceContext.attributes,
);
6.4. Event Handling
Subscribe to provider lifecycle events:
provider.events.listen((event) {
switch (event.type) {
case IntelliToggleEventType.ready:
print('Provider ready');
break;
case IntelliToggleEventType.configurationChanged:
print('Flags updated: ${event.data?['flagsChanged']}');
break;
case IntelliToggleEventType.error:
print('Error: ${event.message}');
break;
}
});
7. Configuration Options
The IntelliToggleOptions class controls how the SDK communicates with IntelliToggle.
7.1. Production Configuration
final options = IntelliToggleOptions.production(
baseUri: Uri.parse('https://api.intellitoggle.com'),
timeout: Duration(seconds: 10),
pollingInterval: Duration(minutes: 5),
);
8. Provider Options
| Option | Description | Default |
|---|---|---|
|
API endpoint used to fetch flag configurations |
|
|
Maximum request duration before failing |
|
|
Whether to poll periodically for configuration changes |
|
|
How often to poll for updates when polling is enabled |
|
|
Enables real-time updates from the service if supported |
|
|
Number of retry attempts for failed requests |
|
|
Enables verbose debug logging for troubleshooting |
|
final provider = IntelliToggleProvider(
clientId: 'client_id',
clientSecret: 'client_secret',
tenantId: 'tenant_id',
options: IntelliToggleOptions(
timeout: Duration(seconds: 15),
enablePolling: true,
pollingInterval: Duration(minutes: 2),
enableStreaming: true,
maxRetries: 5,
enableLogging: true,
),
);
9. Resources
-
OpenFeature Dart SDK: OpenFeature Dart SDK
-
IntelliToggle Provider: IntelliToggle Provider