enabled state and percentage rollout, then individual
workspaces may attach an override row that flips the flag for that workspace
only.
All endpoints require authentication and workspace context. Reads are open to
any workspace role; mutations (flag definition CRUD and per-workspace override
CRUD) require OWNER or ADMIN.
List Feature Flags
key ascending. When the request
carries workspace context, each flag includes the current workspace’s
override state (override_enabled), or null/omitted when no override row
exists for that flag.
Auth: Any authenticated workspace member (read)
Response: 200 OK
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Flag ID (CUID) |
key | string | Unique flag key |
description | string? | Human-readable description |
enabled | boolean | Instance-global default state |
percentage | integer | Rollout percentage (0-100) |
created_at | string | ISO 8601 timestamp |
updated_at | string | ISO 8601 timestamp |
override_enabled | boolean? | Current workspace’s override state; omitted when no override row exists (flag inherits the instance default) |
Create Feature Flag
OWNER or ADMIN role
Request Body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
key | string | Yes | — | Unique flag key |
description | string | No | null | Human-readable description |
enabled | boolean | No | false | Default state |
percentage | integer | No | 0 | Rollout percentage (0-100) |
201 Created — the created flag object (same shape as a List item, without override_enabled).
| Status | Condition |
|---|---|
400 | Missing key, invalid JSON, or percentage outside 0-100 |
403 | Insufficient role |
409 | A flag with this key already exists |
feature_flag.created
Update Feature Flag
OWNER or ADMIN role
| Path Parameter | Description |
|---|---|
key | Flag key |
| Field | Type | Description |
|---|---|---|
description | string | Description; empty string clears it to null |
enabled | boolean | Default state |
percentage | integer | Rollout percentage (0-100) |
200 OK — the updated flag object, including override_enabled for the current workspace (same shape as a List item).
| Status | Condition |
|---|---|
400 | Invalid JSON, percentage outside 0-100, or no fields to update |
403 | Insufficient role |
404 | Flag not found |
feature_flag.updated
Delete Feature Flag
ON DELETE CASCADE on the override table
means all per-workspace override rows are removed too.
Auth: OWNER or ADMIN role
Response: 204 No Content
| Status | Condition |
|---|---|
403 | Insufficient role |
404 | Flag not found |
feature_flag.deleted
Set Workspace Override
PUT with the same body updates the same row in
place (keyed on UNIQUE(flag_id, workspace_id)).
Auth: OWNER or ADMIN role
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
enabled | boolean | Yes | Explicit override value. Must be present — an absent field is rejected (a missing body must not silently disable the flag). |
200 OK
| Status | Condition |
|---|---|
400 | Invalid JSON, missing workspace context, or missing explicit enabled field |
403 | Insufficient role |
404 | Flag not found |
feature_flag.override_set
Clear Workspace Override
204 whether or
not an override row existed (after this call, the override does not exist).
Auth: OWNER or ADMIN role
Response: 204 No Content
| Status | Condition |
|---|---|
400 | Missing workspace context |
403 | Insufficient role |
404 | Flag not found |
feature_flag.override_cleared (only when a row was actually removed)