MachineMachine
MachineMachine
MachineGetting startedQuickstartAccounts & access
Your project
AgentsLegacy kortix.tomlManifest referenceModelsAgent permissionsSecrets
Running work
Change requestsRuntime & sandboxSessions
Connect & automate
ComputersConnectorsInkbox: iMessage, SMS, email & callsMCP serverPixio: images, video & audioRemindersSlack & channelsMicrosoft TeamsTriggers
Feature flags
Apps

Develop

CLI
TypeScript SDKFull exampleAuthenticationSign in with KortixSessionsAppsReact hooksSDK reference
Machine as a BackendAPI reference
GitHub

Feature flags

Turn a Kortix surface on for one project, and read what every flag gates.

A feature flag turns one Kortix surface on for one project. Any surface can ship behind a flag — experimental, beta, or fully stable. "Experimental" is a stability badge on a flag, not the name of the system.

Flags are per project. Turning a flag on in one project changes nothing in another project, and nothing for other accounts.

Apps

Deploy static sites, bundles, Dockerfiles, and OCI images to stable URLs.

Turn a flag on

  1. Open Settings → Experimental. The tab lists every flag the platform supports.
  2. Read the row: the flag name, its stability badge, one sentence of description, and its origin — Default on, Default off, or Overridden for this project.
  3. Use the switch. The change applies to the current project immediately.

You need the project's project.settings.write permission. The route answers 403 for any other caller.

From the CLI

The same switches are available to scripts and agents through kortix projects features:

bash
kortix projects features            # every flag: key, state, origin, stability
kortix projects features enable apps
kortix projects features disable reminders
kortix projects features reset apps  # drop the override; follow the platform default
kortix projects features --json      # the full catalog as JSON

Add --project <id> to act on a project other than the linked/default one. A flag the platform marks unavailable stays off whatever the project override says; the CLI prints that as n/a / unavailable.

:::info[Flag state is not in your repo] Per-project flag state lives in the database, on the project row. It is never read from kortix.yaml. A flag you turn on does not travel with a repository clone or a fork. :::

The two gates

Each flag has two gates. They answer different questions.

GateQuestionEffect when false
availableDoes this deployment support the flag at all?The toggle is hidden and the surface stays dark, whatever the project chose.
enabledIs the flag on for this project?The surface stays dark for this project.

enabled is the project's explicit choice over the platform default, then AND-gated by available. enabled therefore always implies available.

available is an operator decision, made by the environment the API runs in. Two flags read it from configuration; every other flag is always available:

FlagAvailable when
llm_gatewayLLM_GATEWAY_ENABLED is on
monitorsPLATINUM_API_KEY is set

Stability badges

The badge describes the contract, not the switch. A stable flag is still an opt-in: apps is stable and still off by default.

BadgeWhat it means
ExperimentalThe surface and its contract can still change.
BetaThe surface works and the shape is settling.
StableThe contract holds. The flag stays an opt-in.

How a flag is enforced

Every flag declares one enforcement mode.

ModeWhat the server does when the flag is off
routesThe HTTP surface rejects the request with 403.
behavioralThe behavior does not occur — no connector materializes, no env injects, no agent registers.
ui-onlyThe server deliberately does not enforce. The flag hides client surface only.

A routes rejection is identical everywhere:

json
{
  "error": "Apps is not enabled for this project. Enable it in Settings → Feature flags.",
  "code": "feature_disabled",
  "feature": "apps"
}

The error string names the flag list, not a specific tab. The list is the Experimental tab of Settings.

Branch on code, never on the message text. The SDK exports isFeatureDisabledError(error) and featureDisabledKey(error) for exactly this.

Every flag

Registry order — the same order Settings → Feature flags shows.

KeyNameStabilityDefaultEnforcement
marketplaceMarketplaceBetaOnroutes
connectors_api_discoverConnectors API DiscoverExperimentalOffroutes
agentmail_emailAgentMail EmailExperimentalOffroutes
teamsMicrosoft TeamsExperimentalOffroutes
llm_gatewayLLM GatewayExperimentalOn (operator can default off)behavioral
meta_agentMeta AgentExperimentalOffbehavioral
appsAppsStableOffroutes
monitorsMonitorsExperimentalOffroutes
remindersRemindersBetaOffroutes
warm_sessionsWarm SessionsBetaOnroutes
secrets_egressNetwork-Enforced SecretsExperimentalOnbehavioral
pi_harnessPi Harness (in-sandbox)ExperimentalOffbehavioral

llm_gateway reads its per-project default from LLM_GATEWAY_DEFAULT_ENABLED, which defaults to on. Turning the flag off per project is a first-class path: the project runs native OpenCode model management (provider keys injected into the sandbox, native provider/model refs). An explicit project choice always wins.

What each flag gates

  • marketplace — browse and install skills from community and vendor registries.
  • connectors_api_discover — browse direct API, MCP, GraphQL, CLI, and Postman surfaces beside Pipedream OAuth apps. See Connectors.
  • agentmail_email — assign AgentMail inbox connections so inbound email starts and continues sessions.
  • teams — connect a Microsoft Teams bot so chats and channels start and continue sessions. See Slack & channels.
  • llm_gateway — route the project through the managed Kortix LLM gateway. See Models.
  • meta_agent — add a platform-owned coordinator agent that spawns and manages specialized sessions.
  • apps — deploy static sites, bundles, Dockerfiles, and OCI images to stable serverless URLs. See Apps.
  • monitors — run 24/7 watchers from your repo that fire trigger events into sessions. See Triggers.
  • reminders — scheduled check-ins that re-prompt one session, once or on repeat. Off, the reminder routes answer feature_disabled and existing reminders do not fire. See Reminders.
  • warm_sessions — keep one sandbox booted while a project is open, so a new session starts without a cold boot.
  • secrets_egress — offer network enforcement for a secret: the sandbox holds a handle, and Kortix substitutes the real value only on requests to approved hosts. See Secrets.
  • pi_harness — run this project's sessions on the pi agent harness inside the ordinary session sandbox (KORTIX_HARNESS=pi). On: every new or restarted session boots pi, whatever the manifest says. Off: the manifest decides — runtime: pi still boots pi, anything else boots OpenCode. Same repo layout, agents and skills either way; a running session keeps its harness until it is restarted or resumed.

Graduated flags

A graduated feature is on for every project and has no switch.

  • Agents as principals is standard behavior with no switch. An agent session acts as the agent itself — its Machine permissions within its ceiling role, whoever runs it. See Agent permissions.
  • Review Center graduated out of the flag system. The Review page, the sidebar Review row, and the command-palette row show for every project; the project.review.read and project.review.act permissions still apply. review_center is no longer a flag key: PATCH /v1/projects/:id/features answers 400 Unknown feature flag, and kortix projects features enable review_center prints that error and exits 1. A stored override from before graduation has no effect.
  • Computers graduated out of the flag system. Every member can connect their own computer from the project sidebar; the platform's TUNNEL_ENABLED setting is the only gate. agent_tunnel is no longer a flag key: PATCH /v1/projects/:id/features answers 400 Unknown feature flag. See Computers.
  • Microsoft Teams graduated out of the flag system. Every project can connect Teams from Connectors → Channels; a tenant admin still consents once, or the project brings its own bot. teams is no longer a flag key: PATCH /v1/projects/:id/features answers 400 Unknown feature flag. A stored override from before graduation has no effect. See Microsoft Teams.

Side effects of a toggle

Some flags converge platform state after the write commits.

FlagEffect after the toggle
agentmail_emailMachine re-runs channel-connector materialization, so the connector appears or disappears with the flag.
llm_gatewayKortix propagates the new provider mode to active sandboxes.

Effects are convergence work, not part of the toggle's success. The API response does not wait for them. Each effect is retried once, and the reconcilers behind it are idempotent and re-run on their periodic sweeps.

Read and set a flag from code

Read the effective per-project state through the project detail, or through the React hook:

tsx
import { useFeatureFlag } from '@kortix/sdk/react';

function AppsNavItem({ projectId }: { projectId: string }) {
  const apps = useFeatureFlag(projectId, 'apps');
  if (!apps.enabled) return null;
  return <Link href={`/projects/${projectId}/apps`}>Apps</Link>;
}

enabled is true only when the server said exactly true. A missing project id, an in-flight query, and an error all resolve to false. Gate fail-closed.

Set the project override with the client:

typescript
const p = kortix.project(projectId);

await p.updateFeatureFlag('apps', true);   // turn it on for this project
await p.updateFeatureFlag('apps', null);   // clear the override, inherit the default

updateFeatureFlag calls PATCH /v1/projects/:id/features. feature is one of FEATURE_FLAG_KEYS, exported from @kortix/sdk and typed as FeatureFlagKey. See SDK reference.

Handle a disabled feature by code, not by message:

typescript
import { featureDisabledKey, isFeatureDisabledError } from '@kortix/sdk';

try {
  await kortix.project(projectId).apps.list();
} catch (error) {
  if (isFeatureDisabledError(error)) {
    console.log(`${featureDisabledKey(error)} is off for this project`);
  }
}
PreviousTriggersNextApps

On this page

Turn a flag onFrom the CLIThe two gatesStability badgesHow a flag is enforcedEvery flagWhat each flag gatesGraduated flagsSide effects of a toggleRead and set a flag from code