Skip to content

Overview

Feature flags provide kill-switch and gradual rollout capabilities. Flags can be targeted to specific segments, companies, or users.

Base URL

/api/admin/config/features

NOTE

These endpoints require authentication with a Super Admin account.


Endpoints

List Feature Flags

http
GET /api/admin/config/features

Returns all feature flags with their associated segments.

Response 200 OK

json
[
  {
    "id": "feedback_widget",
    "name": "Feedback Widget",
    "description": "Show feedback widget in app",
    "type": "boolean",
    "isEnabled": true,
    "status": "development",
    "companyOverrides": [],
    "userOverrides": ["marc.montecalvo@gmail.com"],
    "segments": [
      {
        "id": "ffs-123",
        "segmentId": "seg-456",
        "segment": {
          "id": "seg-456",
          "name": "beta-testers"
        }
      }
    ],
    "createdAt": "2025-12-01T00:00:00.000Z",
    "updatedAt": "2025-12-10T00:00:00.000Z"
  }
]

Create Feature Flag

http
POST /api/admin/config/features

Request Body

json
{
  "id": "new_dashboard_v2",
  "name": "New Dashboard V2",
  "description": "Redesigned dashboard layout",
  "isEnabled": false,
  "type": "boolean",
  "status": "development"
}
FieldTypeRequiredDefaultDescription
idstring-Code-defined ID (snake_case recommended)
namestring-Human-readable name
descriptionstring-Feature description
isEnabledbooleanfalseGlobal kill switch
typestring"boolean"Flag type
statusstring"development"development, active, deprecated

Response 200 OK - Created flag object


Update Feature Flag

http
PUT /api/admin/config/features/:id

Parameters

NameTypeDescription
idstringFeature flag ID

Request Body - All fields optional

json
{
  "isEnabled": true,
  "description": "Updated description",
  "status": "active",
  "companyOverrides": ["company-123"],
  "userOverrides": ["user@example.com"]
}
FieldTypeDescription
isEnabledbooleanGlobal kill switch
descriptionstringFeature description
statusstringStatus: development, active, deprecated
companyOverridesstring[]Company IDs that always have access
userOverridesstring[]User IDs or emails that always have access

Response 200 OK - Updated flag object


Attach Segment to Flag

http
POST /api/admin/config/features/:id/segments

Parameters

NameTypeDescription
idstringFeature flag ID

Request Body

json
{
  "segmentId": "seg-456"
}

Response 200 OK

json
{
  "id": "ffs-789",
  "featureFlagId": "feedback_widget",
  "segmentId": "seg-456"
}

Detach Segment from Flag

http
DELETE /api/admin/config/features/:id/segments/:segmentId

Parameters

NameTypeDescription
idstringFeature flag ID
segmentIdstringSegment ID to detach

Response 200 OK

json
{
  "success": true
}

Access Evaluation Logic

When checking feature access, the system evaluates in this order:

  1. Direct Overrides - If user/company is in overrides array → ALLOW
  2. Segment Membership - If user/company is in any attached active segment → ALLOW
  3. Global Switch - If isEnabled is true → ALLOW
  4. OtherwiseDENY
typescript
import { isFeatureEnabled } from '../services/featureFlags.service.js';

const hasAccess = await isFeatureEnabled('my_feature', {
  companyId: 'company-123',
  userId: 'user-456',
  email: 'user@example.com'
});

See Also

TendSocial Documentation