This walks through the full loop for a new flag: create it with its variations, configure it for one environment, then evaluate it from application code.
1. Create the flag with its variations
A feature flag belongs to a project, not to a single environment, and it's created together with its variations: POST /v1/projects/{project_id}/feature-flags requires at least two.
const res = await fetch(
`https://api.rollfuse.com/v1/projects/${projectId}/feature-flags`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "New Checkout Flow",
key: "new-checkout-flow",
variations: [
{ key: "on", value: true },
{ key: "off", value: false },
],
}),
}
);
const flag = await res.json();
console.log(flag.id, flag.key);
// flag.variations = [{ id, key: "on", value: true }, { id, key: "off", value: false }]
token here is a session token or an API key with a role that has permission to manage feature flags on the project. key is what your application code references when evaluating the flag; each variation's id is what the environment config below points at.
At this point the flag exists but has no per-environment configuration, so evaluating it anywhere would fall back to whatever value your evaluation call passes in.
2. Turn it on for one environment
Flags are configured per environment, so a flag can be live in staging and untouched in production at the same time. Set (or replace) that config with PUT /v1/environments/{environment_id}/feature-flags/{feature_flag_id}/config, pointing default_variation_id at the variation returned for "on":
const onVariationId = flag.variations.find((v) => v.key === "on").id;
const configRes = await fetch(
`https://api.rollfuse.com/v1/environments/${environmentId}/feature-flags/${flag.id}/config`,
{
method: "PUT",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
enabled: true,
default_variation_id: onVariationId,
rules: [],
}),
}
);
const config = await configRes.json();
This is a PUT, not a PATCH: it replaces the flag's config for this environment wholesale, including its rules. An empty rules array means every subject gets default_variation_id. If you later add targeting rules or a percentage rollout on top of this config, you'll be updating this same resource, not creating a new one.
3. Read the flag from application code
Evaluation happens through @rollfuse/sdk-js, which reads from a synced local snapshot rather than making a REST call per evaluation:
import { RollfuseClient } from "@rollfuse/sdk-js";
const client = new RollfuseClient({
baseUrl: "https://api.rollfuse.com",
credential: process.env.ROLLFUSE_CREDENTIAL!, // set before running
});
await client.start();
const result = client.evaluate("user-42", "new-checkout-flow", {
attributes: { plan: "pro" },
fallback: false,
});
console.log(result.value); // true, once the environment config above is live
console.log(result.reason); // why this value was returned
console.log(result.variation_key); // "on"
credential here is an SDK-specific environment credential, separate from the token used against the REST API in the previous two steps. The REST API is how you administer flags; the SDK is how your running application reads them.
If you need every flag's value for a given subject at once, instead of one flag at a time, use client.evaluateAll("user-42", { attributes: { plan: "pro" } }), which returns the same shape keyed by flag key.
Where to go next
Once a flag reads correctly at 100% in one environment, the next step is usually not "on for everyone at once": see the percentage rollout tutorial for how to ramp it up gradually with deterministic bucketing.