Third-Party Integration Checklist
Use this checklist when integrating IntelliToggle into another product, service, or customer backend. The goal is that an external team can sign up, create credentials, run one smoke test, and then add flag evaluation to production code without Aortem-only knowledge.
What A Clean Integration Looks Like
A clean IntelliToggle integration has these properties:
-
The customer can sign up and complete billing without manual support.
-
The customer lands in an active tenant with an active subscription context.
-
The tenant has at least one project, one environment, and one feature flag.
-
The customer creates an OAuth2 client with least-privilege scopes.
-
The customer stores credentials in a secret manager, not source control.
-
The customer can exchange credentials for an access token.
-
The customer can evaluate a flag from a backend service.
-
The customer can identify failures from clear status codes and logs.
For server-side integrations, do not use a user Firebase token in production service code. Use OAuth2 Client Credentials.
Supported OAuth2 Flow
IntelliToggle supports OAuth2 Client Credentials for backend and service-to-service integrations. This is the standard machine-to-machine flow where the integrating service exchanges a client_id and client_secret for a short-lived bearer token.
This flow does not use redirect URLs or browser consent screens. Redirect-based authorization code flows are for user-facing delegated access and are not the IntelliToggle runtime integration path today.
Use one OAuth client per consuming service and environment. For example, create separate clients for billing-api-dev and billing-api-prod.
Runtime URLs
| Environment | API URL | Token URL |
|---|---|---|
Production |
||
Development preview |
Use the API URL shown in the generated integration bundle |
Use the token URL shown in the generated integration bundle |
Do not mix environments. A client created in the development preview must be tested against the development API. A client created in production must be tested against the production API.
Sandbox Lifecycle
Sandbox workspaces are temporary evaluation accounts. They last for 7 days.
Sandbox workspaces include preloaded demo data so customers can test login, OAuth2 client creation, token exchange, project/flag listing, and flag evaluation without building their own workspace data first. Customer-created projects, environments, and flags are paid-workspace capabilities.
If the customer does not upgrade before the sandbox expires, IntelliToggle deletes the sandbox tenant and its workspace data. That includes sandbox projects, flags, OAuth clients, tenant membership, user profile records tied only to the sandbox, and Firebase auth access for that sandbox user.
If the customer upgrades to Standard, Enhanced, or Enterprise before cleanup runs, the backend converts the tenant to a paid workspace:
-
is_sandboxis cleared. -
sandbox_accountmetadata is removed. -
demo sandbox projects and flags are removed.
-
the customer creates production integration data in the paid workspace.
-
cleanup no longer treats the tenant as eligible for sandbox deletion.
Production integrations should not be created as sandboxes. Use the sandbox only for short-lived evaluation. Use paid checkout before any integration data needs to be retained.
Required Values
Every backend integration should be configured with these values:
INTELLITOGGLE_API_URL=https://api.intellitoggle.com
INTELLITOGGLE_TOKEN_URL=https://api.intellitoggle.com/api/v1/oauth/token
INTELLITOGGLE_CLIENT_ID=client_xxx
INTELLITOGGLE_CLIENT_SECRET=secret_xxx
INTELLITOGGLE_TENANT_ID=tenant_xxx
INTELLITOGGLE_PROJECT_ID=project_xxx
INTELLITOGGLE_ENVIRONMENT=production
INTELLITOGGLE_FLAG_KEY=your-flag-key
Keep INTELLITOGGLE_CLIENT_SECRET in Secret Manager, your CI secret store, or your runtime platform’s secret facility.
Dashboard Setup
-
Sign up at IntelliToggle.
-
Complete billing for the plan you want to test.
-
Create a project for the integrating app, such as
Billing API. -
Use
productionas the first environment unless you need separate staged rollout validation. -
Create a boolean flag, for example
service-runtime-enabled. -
Open Settings > Applications.
-
Create an OAuth2 client.
-
Select only the scopes needed by the integration.
Recommended minimum scopes for runtime flag evaluation:
-
flags:read -
flags:evaluate -
projects:read
Only add flags:write or projects:write for automation that creates or updates resources.
Smoke Test The Credentials
First exchange the OAuth2 client credentials for a short-lived access token:
TOKEN_RESPONSE=$(curl -sS -X POST "$INTELLITOGGLE_TOKEN_URL" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "client_id=$INTELLITOGGLE_CLIENT_ID" \
--data-urlencode "client_secret=$INTELLITOGGLE_CLIENT_SECRET" \
--data-urlencode "scope=flags:read flags:evaluate")
ACCESS_TOKEN=$(printf '%s' "$TOKEN_RESPONSE" | jq -r '.access_token')
Then evaluate a flag:
curl -sS -X POST "$INTELLITOGGLE_API_URL/api/v1/flags/$INTELLITOGGLE_FLAG_KEY/evaluate" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: $INTELLITOGGLE_TENANT_ID" \
-H "X-Environment: $INTELLITOGGLE_ENVIRONMENT" \
-d '{
"targetingKey": "integration-smoke-test",
"attributes": {
"service": "billing-api",
"environment": "production"
}
}'
Expected result: HTTP 200 with the evaluated value or default value. A 401 means the token is missing or invalid. A 403 usually means the client is inactive, expired, missing a required scope, or the subscription/tenant is not active. A 404 means the flag key, tenant, or route is wrong.
Dart Server Integration Pattern
Initialize the provider once at process startup and reuse it. Do not create a new provider per request.
import 'dart:io';
import 'package:openfeature_provider_intellitoggle/openfeature_provider_intellitoggle.dart';
Future<IntelliToggleClient> createIntelliToggleClient() 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 featureClient = FeatureClient(
metadata: ClientMetadata(name: 'billing-api', version: '1.0.0'),
provider: provider,
hookManager: HookManager(),
defaultContext: EvaluationContext(attributes: {
'service': 'billing-api',
'environment': Platform.environment['INTELLITOGGLE_ENVIRONMENT'] ??
'production',
}),
);
return IntelliToggleClient(featureClient);
}
Use stable targeting keys. For user-facing checks, use a stable user id. For service-level checks, use a stable service key such as billing-api-prod.
final enabled = await client.getBooleanValue(
'service-runtime-enabled',
false,
targetingKey: 'billing-api-prod',
evaluationContext: {
'service': 'billing-api',
'region': 'us-central1',
},
);
Production Rules
-
Use OAuth2 client credentials for backend services.
-
Store secrets in Secret Manager or the runtime secret store.
-
Use one initialized SDK/provider per process.
-
Fail safely with defaults if IntelliToggle is temporarily unavailable.
-
Keep flag keys stable once they are used by production code.
-
Use least-privilege scopes.
-
Rotate OAuth clients when a secret may have been exposed.
-
Separate dev and prod tenants or credentials when the consuming app has separate environments.
If any integration step requires manual database access, direct Firebase manipulation, or Aortem-only credentials, the public integration path is not clean enough yet.