Environments
An environment is a named deployment stage your code runs in: development, staging, production, mike-laptop, pr-1234. Every flag evaluation, logger level, and config read is scoped to an environment, so the same code can serve different values in different places without changing.
A concrete example
Your payments service runs in three places: a developer's laptop, a staging cluster, and production. Each instance is configured with a different environment value:
SMPLKIT_ENVIRONMENT=mike-laptop # the developer
SMPLKIT_ENVIRONMENT=staging # the staging cluster
SMPLKIT_ENVIRONMENT=production # the prod clusterWhen the laptop instance boots, smplkit notices a brand-new environment (mike-laptop) and creates it automatically as an ad-hoc environment, hidden by default in the developer console. The other two are standard environments — visible to everyone, ordered as staging then production in the console column grid.
How environments are created
Environments come into existence in two ways:
Auto-registration (most common)
When the SDK initializes with environment="mike-laptop", the client posts to /api/v1/contexts/bulk with the environment name. If the environment doesn't exist yet, the platform creates it with classification = AD_HOC — meaning it's a personal/temporary environment, hidden from the default column grid until someone promotes it.
This is how every developer can have their own environment without coordinating with anyone else.
Manual creation
An OWNER or ADMIN can create an environment explicitly through the console at /platform/environments or via the API:
curl -X POST https://app.smplkit.com/api/v1/environments \
-H "Authorization: Bearer $SMPLKIT_API_KEY" \
-H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
"type": "environment",
"id": "production",
"attributes": {
"name": "Production",
"color": "#dc2626",
"classification": "STANDARD"
}
}
}'id is the environment key — a stable identifier used in URLs and SDK config. Manually-created environments default to STANDARD classification.
Standard vs ad-hoc
Each environment has two orthogonal flags:
| Axis | Values | What it controls |
|---|---|---|
classification | STANDARD / AD_HOC | Origin and default visibility in the grid |
managed | true / false | Whether per-environment values can be written to it, and whether it counts against the platform.managed_environments quota |
The two are independent — a STANDARD environment can be unmanaged (you can see it as a comparison column but not write per-env values), and an AD_HOC environment can be promoted to managed.
Classification — origin and default visibility
STANDARD— Canonical environments (development,staging,production, etc.). Visible to all account members by default. Appear as columns in the environment grid in account-defined order.AD_HOC— Personal or temporary environments (a developer's laptop, a PR preview, a load-test cluster). Hidden from the default grid; users opt into seeing them.
Auto-registered environments land AD_HOC. Manually-created environments land STANDARD. Either can be flipped by an admin.
Managed — control and gating
managed = true— Per-environment values (flag rules, config overrides, logger levels) can be written against this environment. Counts against yourplatform.managed_environmentsplan quota.managed = false— View-only. Existing values still resolve at runtime and render as a comparison column in the grid, but writes that set a per-environment value get rejected with 400environment_unmanaged. Promote it first to enable writes.
production is a special case: the platform guarantees it exists and is always managed. It cannot be deleted or demoted to unmanaged.
A new free account is seeded with:
development—STANDARD,managed = truestaging—STANDARD,managed = false(visible as a comparison column; promote to enable writes)production—STANDARD,managed = true(and locked managed)
This puts you at 2/2 of the Free plan's platform.managed_environments quota with staging available as a clear promote-flow demo. See Promote an environment.
The environment grid
All three products (Flags, Config, Logging) render their data as a grid: resources on rows, environments on columns. The column ordering and visibility comes from two layers:
- Account level (admin-controlled). A list of standard environment keys, ordered. This is the default view every user sees.
- User level (personal). A per-user override that lets each person reorder, hide, or add ad-hoc environments to their own view.
A user without a personal override sees the account default. A user who reorders columns is editing only their own view — they don't change anyone else's. See Manage environment display.
What promotion and demotion do
The console exposes two independent "promote" buttons per environment, each flipping one of the two axes:
Classification promotion / demotion (display)
Changes the classification axis. Has asymmetric effects on display:
- Promote (AD_HOC → STANDARD): Backend appends the environment to the account-level order and to every user's personal order that doesn't already include it. After promotion, everyone sees the new column (unless they've explicitly hidden it).
- Demote (STANDARD → AD_HOC): Backend removes the environment from the account-level order only. Users who had personalized to include it keep seeing it. New users (with no personal order) won't.
Demotion is intentionally non-disruptive — if someone has been using an environment, hiding it from defaults doesn't yank it out of their view.
Managed promotion / demotion (control)
Changes the managed axis. Consumes or frees a platform.managed_environments quota slot:
- Promote (
managed = false→true): Enables per-environment value writes on flags / config / loggers. Counts against the account's plan quota — at-limit promotions return 402 Payment Required. If a customer is already at their limit, they need to demote another environment first or upgrade their plan. - Demote (
managed = true→false): Frees a quota slot. Per-environment values across all products are retained but frozen — runtime evaluations still see them, but new writes are rejected withenvironment_unmanaged. Re-promoting restores write access without data loss.
production cannot be demoted to managed = false and cannot be deleted. Every account is guaranteed a managed production to write to.
Limits
platform.managed_environments is a plan-resolved entitlement — only environments with managed = true count. Free starts at 2, Enterprise is unlimited. See Subscriptions and entitlements for the full table.
Unmanaged environments don't count against the quota — auto-discovered AD_HOC environments stay free as long as no one promotes them to managed.
Deleting environments
Deleting an environment removes the registry row. By itself, it does not clear per-environment configuration that other resources hold:
- Flag rules and env-level flag defaults scoped to the deleted environment
- Per-key config overrides scoped to the deleted environment
- Per-env logger level overrides
Two things to know before you delete:
- The console offers a cascade option (default checked) that wipes those references along with the environment row. The delete dialog reports how many of each kind exist and lets you uncheck the cascade if you have a reason to leave the per-env data behind. Each cascaded edit emits its own
smpl.flag.updated/smpl.config.updated/smpl.logger.updatedaudit event, attributed to the user who triggered the delete. The API equivalent isDELETE /api/v1/environments/{id}?cascade=true(defaultcascade=falsepreserves the bare-row delete behavior). - A running SDK will recreate the environment. If any service is still initializing the smplkit SDK with the deleted environment name, its next checkin re-creates the environment as
AD_HOC. Any per-env configuration you preserved by skipping cascade then becomes active again. To prevent recreation, update the affected services to use a different environment name (or stop them from reporting in) before you delete.
If you only want to hide an environment from the default column ordering — not delete it — use demote (Standard → Ad-hoc) instead. See Promote an environment for the inverse.
Environments are referenced by key
Environments are identified by their key (e.g. production), not a UUID. Keys appear in URL paths (/api/v1/environments/production), in flag/config environment overrides (flag.environments.production), and in the SDK's runtime configuration. Renaming an environment cascades the rename across all flags and configs that reference it.
Who can do what
| Action | OWNER | ADMIN | MEMBER | VIEWER |
|---|---|---|---|---|
| Read environments | ✓ | ✓ | ✓ | ✓ |
| Rename, recolor | ✓ | ✓ | ✓ | |
| Create | ✓ | ✓ | ||
| Promote / demote classification | ✓ | ✓ | ||
| Promote / demote managed | ✓ | ✓ | ||
Delete (any non-production env) | ✓ | ✓ | ||
| Reorder personal view | ✓ | ✓ | ✓ | ✓ |
| Reorder account default | ✓ | ✓ |

