Advanced Topics

This page covers advanced scenarios and integrations for using Intellitoggle in Dart, server environments, and Flutter applications. If you are new to Intellitoggle, start with SDK Usage first.

1. Local Development

During development you may want to test feature flags without connecting to the Intellitoggle cloud service. The InMemoryProvider makes it easy to define and update flags at runtime.

final provider = InMemoryProvider();

// Set test flags
provider.setFlag('feature-enabled', true);
provider.setFlag('api-version', 'v2');
provider.setFlag('rate-limits', {
  'requests_per_minute': 1000,
  'burst_size': 50,
});

await OpenFeatureAPI().setProvider(provider);

// Evaluate flags
final client = IntelliToggleClient(FeatureClient(
  metadata: ClientMetadata(name: 'test'),
  hookManager: HookManager(),
));

final enabled = await client.getBooleanValue('feature-enabled', false);
print('Feature enabled: $enabled');

// Update flags at runtime
provider.setFlag('feature-enabled', false);

2. OREP Server

For remote evaluation, Intellitoggle supports the Open Remote Evaluation Protocol (OREP).

Start remote evaluation server
dart run bin/orep_server.dart
Environment variables
OREP_HOST=0.0.0.0
OREP_PORT=8080
OREP_AUTH_TOKEN=secure-token-123
Test evaluation
curl -X POST http://localhost:8080/v1/flags/my-flag/evaluate \
  -H "Authorization: Bearer secure-token-123" \
  -H "Content-Type: application/json" \
  -d '{
    "defaultValue": false,
    "type": "boolean",
    "context": {
      "targetingKey": "user-123",
      "role": "admin"
    }
  }'

3. API Integration

3.1. OAuth2 Token Exchange

Obtain an access token for API calls:

Future<String> getAccessToken() async {
  final response = await http.post(
    Uri.parse('https://api.intellitoggle.com/oauth/token'),
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    body: 'grant_type=client_credentials'
        '&client_id=$clientId'
        '&client_secret=$clientSecret'
        '&scope=flags:read flags:evaluate',
  );

  if (response.statusCode == 200) {
    final data = jsonDecode(response.body);
    return data['access_token'];
  }
  throw Exception('OAuth2 failed: ${response.body}');
}

3.2. Direct API Calls

Call the evaluation endpoint directly:

Future<Map<String, dynamic>> evaluateFlag({
  required String flagKey,
  required String projectId,
  required Map<String, dynamic> context,
}) async {
  final token = await getAccessToken();

  final response = await http.post(
    Uri.parse('$baseUrl/api/flags/projects/$projectId/flags/$flagKey/evaluate'),
    headers: {
      'Authorization': 'Bearer $token',
      'X-Tenant-ID': tenantId,
      'Content-Type': 'application/json',
    },
    body: jsonEncode(context),
  );

  if (response.statusCode == 200) {
    return jsonDecode(response.body);
  }
  throw Exception('Evaluation failed: ${response.body}');
}

4. Error Handling

4.1. Exception Types

try {
  final result = await client.getBooleanValue('my-flag', false);
} on FlagNotFoundException {
  // Flag doesn't exist
} on AuthenticationException {
  // Invalid credentials
} on ApiException catch (e) {
  // API error with status code
  print('API error: ${e.code}');
} catch (e) {
  // General error
}

4.2. Retry Configuration

final options = IntelliToggleOptions(
  maxRetries: 3,
  retryDelay: Duration(seconds: 1),
  timeout: Duration(seconds: 10),
);

5. Hook System

Hooks let you intercept flag evaluations globally or per-client.

5.1. Console Logging Hook

final hook = ConsoleLoggingHook();

// Add globally
OpenFeatureAPI().addHooks([hook]);

// Add to specific client
final hookManager = HookManager();
hookManager.addHook(hook);

5.2. Custom Analytics Hook

class AnalyticsHook extends Hook {
  @override
  Future<void> after(HookContext context) async {
    // Track flag usage
    analytics.track('flag_evaluated', {
      'flag_key': context.flagKey,
      'result': context.result,
    });
  }
}

6. Flutter Integration (Brief)

For Flutter apps, IntelliToggle can be integrated with state management and direct API calls.

# pubspec.yaml
dependencies:
  flutter_dotenv: ^5.2.1
  provider: ^6.1.5
// Basic Flutter service
class IntelliToggleService extends ChangeNotifier {
  Future<String> getAccessToken() async {
    // OAuth2 implementation
  }

  Future<Map<String, dynamic>> evaluateFlag({
    required String projectId,
    required String flagKey,
    required Map<String, dynamic> context,
  }) async {
    // Direct API calls
  }
}

See the sample Flutter app for a full implementation.

7. Context Types

7.1. Single Context

{
  "targetingKey": "user-123",
  "kind": "user",
  "role": "admin",
  "plan": "enterprise"
}

7.2. Multi-Context

{
  "kind": "multi",
  "user": {
    "targetingKey": "user-123",
    "role": "admin"
  },
  "organization": {
    "targetingKey": "org-456",
    "plan": "enterprise"
  }
}

7.3. Reserved Attributes

  • targetingKey – Required identifier for targeting

  • kind – Context type (user, organization, device, multi)

  • anonymous – Anonymous context flag

  • privateAttributes – Attributes to exclude from logs

8. OREP/OPTSP Support

8.1. OREP Endpoints

  • POST /v1/flags/{flagKey}/evaluate – Evaluate flag

  • GET /v1/provider/metadata – Provider info

8.2. OPTSP Endpoints

  • POST /v1/provider/seed – Seed test flags

  • POST /v1/provider/reset – Clear all flags

  • POST /v1/provider/shutdown – Shutdown provider

8.3. Authentication

All endpoints require Bearer token:

curl -H "Authorization: Bearer changeme-token" ...

9. Security

9.1. TLS Requirements

Production deployments require HTTPS endpoints. HTTP is only allowed for localhost.

9.2. Token Management

  • Client secrets are never logged or exposed

  • Tokens have configurable TTL (default: 60 minutes)

  • Automatic token refresh with 10-minute buffer

9.3. Tenant Isolation

All requests include the X-Tenant-ID header for multi-tenancy:

headers: {
  'Authorization': 'Bearer $token',
  'X-Tenant-ID': '$tenantId',
}