First steps
Your first feature flag
Create a flag in the dashboard, evaluate it from any SDK with cohort targeting and exposure tracking, and ship a 1% → 100% rollout.
Sankofa Switch is the feature-flag system shared by every SDK. Flags evaluate locally against a decision snapshot — a single payload returned by the engine on app launch — so reads are free and there's no per-flag round trip. Targeting (cohort, % rollout, variants, dependencies) all happens server-side; the SDK just looks up the answer.
This guide takes you through the full lifecycle: create → evaluate → roll out → halt.
1. Create the flag in the dashboard
Open Switch → Flags
From the project nav, open Switch → Flags and click New flag.
Pick a stable key
Use snake_case. The key is the contract you'll reference from code:
new_checkout,dark_mode_default,pricing_v2.Choose a flag type
For your first flag, pick Boolean. Variants and JSON values come later — see the Switch overview.
Save with rollout = 0%
The flag now exists, evaluates to
falsefor everyone, and is ready to be referenced from code without changing user-visible behavior.
2. Evaluate the flag from your SDK
The first call to a flag triggers a handshake with the engine, which returns the full decision snapshot. Subsequent calls are cache reads — no network. The snapshot is refreshed on app launch, on resume, and via ETag every 30 seconds while the app is foregrounded.
import { Sankofa } from "@sankofa/browser";
import { switchPlugin, getSwitch } from "@sankofa/switch";
await Sankofa.init({
apiKey: process.env.NEXT_PUBLIC_SANKOFA_KEY!,
endpoint: "https://api.sankofa.dev",
plugins: [switchPlugin()],
});
const flags = getSwitch()!;
if (flags.getFlag("new_checkout")) {
renderNewCheckout();
} else {
renderClassicCheckout();
}import 'package:sankofa_flutter/sankofa_flutter.dart';
final flags = SankofaSwitch(defaults: {'new_checkout': false});
await Sankofa.instance.init(
apiKey: 'sk_live_...',
endpoint: 'https://api.sankofa.dev',
);
if (flags.getFlag('new_checkout')) {
showNewCheckout();
} else {
showClassicCheckout();
}import { Sankofa, SankofaSwitch } from "@sankofa/react-native";
const flags = new SankofaSwitch({ defaults: { new_checkout: false } });
Sankofa.initialize("sk_live_...", {
endpoint: "https://api.sankofa.dev",
});
if (flags.getFlag("new_checkout")) {
// ...
}import Sankofa
Sankofa.shared.initialize(
apiKey: "sk_live_...",
config: SankofaConfig(endpoint: "https://api.sankofa.dev")
)
_ = SankofaSwitch.shared.withDefaults(["new_checkout": false])
if SankofaSwitch.shared.getFlag("new_checkout") {
showNewCheckout()
}import dev.sankofa.sdk.Sankofa
import dev.sankofa.sdk.switchmod.SankofaSwitch
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
Sankofa.init(this, "sk_live_...", SankofaConfig())
SankofaSwitch.init(this, mapOf("new_checkout" to false))
}
}
if (SankofaSwitch.getFlag("new_checkout")) {
showNewCheckout()
}import { Sankofa } from "@sankofa/node";
Sankofa.init({ apiKey: process.env.SANKOFA_KEY! });
const enabled = await Sankofa.flags.get("new_checkout", {
distinctId: req.user?.id ?? "anon",
defaultValue: false,
});
if (enabled) {
// ...
}enabled, err := client.Flags.Get(ctx, "new_checkout", sankofa.FlagOptions{
DistinctID: userID,
DefaultValue: false,
})
if err == nil && enabled {
// ...
}enabled = sankofa.flags.get(
"new_checkout",
distinct_id=request.user.id,
default_value=False,
)
if enabled:
...boolean enabled = Sankofa.flags().get("new_checkout",
FlagOptions.builder()
.distinctId(user.getId())
.defaultValue(false)
.build());
if (enabled) {
// ...
}3. Roll it out gradually
Open the flag in the dashboard and bump rollout from 0% upward.
Pick a target audience
By default, rollout applies to everyone. Restrict to internal staff first by adding a cohort filter:
email ends_with "@yourcompany.com". The next handshake (≤ 30 seconds) routes the new payload only to matched users.Stage 1 — 5% canary
Lift rollout to 5% within the cohort. Sankofa hashes the distinct ID into a stable bucket, so the same user gets the same answer across sessions and devices.
Stage 2 — 25%, 50%, 100%
Watch the Exposures chart and the Catch crash rate. If both stay healthy, climb to 100%. If error rate jumps, halt the flag (next step).
4. Halt on a bad signal
A flag can be halted in three ways:
- Manually — flip the Halt switch in the dashboard. Every SDK reverts to defaults on the next handshake (≤ 30 seconds).
- Auto, from Catch — wire a halt rule in the dashboard: "if
checkout_error_rate > 1%for the last 5 minutes, haltnew_checkout." Catch posts to the halt webhook automatically. - Programmatically — POST to
/api/switch/halt-webhookfrom CI, PagerDuty, or any external system. See the halt-webhook reference.
When halted, the SDK returns the default value you passed in step 2 — that's why shipping a safe default matters.
What you just shipped
You now have a flag that:
- evaluates locally with zero per-call latency;
- routes via a stable cohort + percentage bucket;
- reports per-call exposures so the dashboard can show real adoption;
- halts globally on a bad signal in under a minute.
That's the foundation Switch builds on for variants, A/B experiments, and scheduled rollouts.