Critical Environments
The audit log tells you what changed in production and who changed it. A critical environment adds the why. Each environment’s settings have a Critical environment section with two switches:
- Require a change reason. Every change to what the environment serves needs a written reason, which goes into the audit log. The server enforces it. So it holds for the dashboard, the Management API, the MCP server and anything else built on the API. Business and Enterprise plans.
- Require typing the environment key. Before a change goes through, the dashboard asks you to type the environment’s key. It guards against working in the wrong tab and lives in the dashboard alone. Every plan.
An environment with either switch on shows a Critical badge on the Environments page.
Turning the settings on
Section titled “Turning the settings on”- Open the Environments page and edit the environment.
- Under Critical environment, switch on Require a change reason, Require typing the environment key, or both.
- Save.
Any member who can edit the environment can turn a setting on. Turning one off takes an Admin or Owner plus a reason of its own, so the audit log shows who lowered the guard and why, and the rule is identical on the API and MCP.
New projects start with the guard up. Their production environment gets Require typing the environment key on every plan, plus Require a change reason on Business and Enterprise. Existing projects keep whatever they have.
What needs a reason
Section titled “What needs a reason”When Require a change reason is on, these changes in that environment need one:
- turning the flag on or off
- the default variation, off variation, rollout and prerequisites
- targeting rules: adding, editing, removing, reordering, or replacing them all at once
- copying a flag’s configuration into the environment, as described in Compare and Copy Environments
- creating or cancelling a scheduled change
- revoking one of its SDK keys
- deleting the environment
Some changes reach every environment in a project at once. Edit a variation’s value, or a segment that rules depend on, and every environment using it serves the new version. These need a reason as soon as any environment in the project requires one:
- creating, editing or deleting a segment
- adding, editing or removing a variation
- archiving, restoring or deleting a flag, including the bulk versions
- hiding a flag from client-side SDKs, or showing it to them
- deleting the project
Creating a flag needs no reason, because a new flag starts off everywhere. Edits to a flag’s name, description, tags, owner or expiry date are exempt as well, along with creating or renaming an environment, creating an SDK key, and anything to do with webhooks.
One reason covers a bulk change, and every audit entry it produces carries it.
In the dashboard
Section titled “In the dashboard”Make a change that needs a reason and the dashboard asks for one before it saves. If the environment also wants its key typed, both fields share one dialog. Cancel, and nothing is saved.
From the Management API
Section titled “From the Management API”Send the reason in the X-Intent-Reason header on the request that makes the change:
curl -X POST "https://api.featureflip.io/api/v1/orgs/acme/projects/checkout/flags/new-checkout/environments/production/toggle" \ -H "Authorization: Bearer $FEATUREFLIP_TOKEN" \ -H "Content-Type: application/json" \ -H "X-Intent-Reason: Rolling back after the 14:02 error spike, INC-412" \ -d '{"enabled": false}'Encode the value as percent-encoded UTF-8. Plain ASCII letters, digits and punctuation pass through untouched, so most reasons need no encoding. Line breaks and tabs are allowed once encoded (%0A, %09), but any other control character gets a 400 with validation_failed. Featureflip trims the value and keeps the first 2,048 characters, and it treats a missing or empty header, or one holding nothing but whitespace and invisible characters, as no reason at all.
Leave it out where one is required and the change is refused with 422 and change_reason_required. Nothing is written. Retry the same request with the header added.
You can send the header on any write, guarded or not, and whatever you put in it lands in the audit log.
Check your automation before you turn the setting on. A deploy script or CI job that changes flags in that environment through the API must send the header as well, or its next change there gets refused. The flag cleanup Action already does, from v2.6.0: each archive names the pull request that removed the flag.
From MCP
Section titled “From MCP”Every MCP write tool that makes one of these changes takes an optional reason argument: toggle_flag, update_flag_environment_config, update_targeting, manage_targeting_rule, manage_segment, manage_variation, update_flag, manage_sdk_key, archive_flag, restore_flag and delete_flag. The server sends it as X-Intent-Reason. Leave it out on a critical environment and the error tells the agent to retry with a reason. Expect it to ask you why.
manage_environment flips the two switches with require_change_reason and require_confirmation. Turning one off from MCP follows the same rule as everywhere else: an Admin or Owner token, plus a reason.
Scheduled changes keep their reason
Section titled “Scheduled changes keep their reason”The reason you give when you schedule a change is stored with it, and when the change applies, maybe days later, its audit entry carries the same words.
A change scheduled without a reason before the environment turned critical still applies on time. Its audit entry gets a generated reason saying so, such as Scheduled on 2026-11-04 09:30 UTC without a change reason.
Cancelling a pending change in a critical environment takes its own reason. That one goes on the cancellation’s entry.
Where reasons show up
Section titled “Where reasons show up”An audit entry with a reason shows it as a quoted line under the action, on the Audit Log page and on a flag’s History tab. Any environment, critical or not.
If your plan changes
Section titled “If your plan changes”Below Business, Require a change reason stops being enforced. The switch stays on where you left it, and writes go through without a reason. You can still switch it off. Switching it back on waits until you move up again. Require typing the environment key is on every plan, so a plan change leaves it alone.
Next steps
Section titled “Next steps”- How to Manage Environments: create environments and their SDK keys
- Audit Log: read the reasons back, with who made each change and when
- Scheduled Changes: queue a change for later, reason included
- Plans and limits: what each plan includes