Flagify is a plain-PHP REST API for self-hosted feature management.
It now supports:
- projects
- environments per project
- clients per project
- first-class identities and identity traits
- flags with variants, prerequisites, expiry, and stale-state tracking
- reusable segments
- per-environment targeting rules
- per-client overrides
- audit logs, analytics, change requests, import/export, and code reference ingestion
- evaluation event capture
- runtime resolution and local-evaluation snapshots
In this API, a client is a customer account inside a project, for example acme-inc.
- PHP 8.3+
- PDO
- MySQL 8+
- Apache/cPanel compatible
- No Composer runtime dependency
Copy .env.example to .env and set:
DB_DRIVERDB_HOSTDB_PORTDB_DATABASEDB_USERNAMEDB_PASSWORDFLAGIFY_BOOTSTRAP_KEY
- Create the MySQL database.
- Run:
php bin/migrate.phpThe migrator now records applied files in schema_migrations, so reruns skip already-applied migrations.
- Start the app:
php -S 127.0.0.1:8080 index.phpEach new project gets three environments automatically:
developmentstagingproduction
production is the default environment used when runtime requests do not specify one.
Segments are reusable rule sets based on client attributes such as:
keynamemetadata.planmetadata.countrymetadata.app_version
Each flag can define environment-specific rules with:
- ordered condition matching
- reusable segment references
- sticky percentage rollouts
- scheduled activation windows
- direct served values or served variants
Flags can define named variants with:
- variant key
- variant value
- optional JSON payload
This lets Flagify act as both a feature-flag service and a light remote-config service.
Flags can depend on other flags by expected value or variant.
Flagify can export an environment snapshot for local/offline evaluation consumers:
GET /api/v1/runtime/projects/{projectId}/environments/{environmentKey}/snapshot
Every runtime resolution writes evaluation events with:
- project
- environment
- flag
- client
- served value
- variant
- evaluation reason
- matched rule
- evaluation context
Main resource groups:
ProjectsEnvironmentsSegmentsFlagsClientsOverridesEventsKeysRuntime
Important runtime endpoints:
GET /api/v1/runtime/configGET /api/v1/runtime/config/{flagKey}GET /api/v1/runtime/projects/{projectId}/clients/{clientKey}/configGET /api/v1/runtime/projects/{projectId}/clients/{clientKey}/config/{flagKey}GET /api/v1/runtime/projects/{projectId}/environments/{environmentKey}/clients/{clientKey}/configGET /api/v1/runtime/projects/{projectId}/environments/{environmentKey}/clients/{clientKey}/config/{flagKey}POST /api/v1/runtime/projects/{projectId}/environments/{environmentKey}/identities/evaluatePOST /api/v1/runtime/projects/{projectId}/environments/{environmentKey}/identities/{kind}/{identifier}/configPOST /api/v1/runtime/projects/{projectId}/evaluation-events:batchGET /api/v1/runtime/projects/{projectId}/environments/{environmentKey}/snapshot
Important admin endpoints:
POST /api/v1/projects/{projectId}/environmentsPOST /api/v1/projects/{projectId}/identitiesPATCH /api/v1/projects/{projectId}/identities/{identityId}/traitsPOST /api/v1/projects/{projectId}/segmentsPUT /api/v1/projects/{projectId}/flags/{flagId}/environments/{environmentKey}POST /api/v1/projects/{projectId}/change-requestsGET /api/v1/projects/{projectId}/analytics/evaluations/by-flagGET /api/v1/projects/{projectId}/audit-logsGET /api/v1/projects/{projectId}/exportPOST /api/v1/projects/{projectId}/importPOST /api/v1/projects/{projectId}/code-referencesGET /api/v1/projects/{projectId}/flags/stale-reportGET /api/v1/projects/{projectId}/evaluation-events
Runtime evaluation now resolves a normalized subject:
kindidentifiertraitsmetadataas a compatibility alias of effective traits- optional
clientdetails for legacy client-backed evaluation
Compatibility rules:
- existing
/clients/...runtime endpoints are unchanged - every active client is mapped to an identity of kind
client - persisted identity traits are authoritative
- transient request traits override persisted traits for that evaluation only
- when a client has no persisted identity traits,
client.metadatastill seeds evaluation
The environment snapshot endpoint is now versioned in-band and returns:
schema_version: 2026-03-23.v1meta.snapshot_checksumETagmatching the checksumpoll_ttl_seconds- explicit evaluation and trait precedence metadata
Polling contract:
- poll on
poll_ttl_seconds - add up to 20% jitter client-side
- keep serving the last good snapshot on refresh failures
- mark the snapshot stale after
3 * poll_ttl_seconds - use
If-None-Matchto receive304 Not Modified
Operational APIs added in this expansion:
- audit logs for admin mutations
- evaluation analytics grouped by flag, variant, and environment
- protected environments with opt-in change request gating
- deterministic project import/export
- code reference ingestion plus stale-flag reporting
Protected environments set requires_change_requests=true. In those environments, direct flag environment PUT/DELETE calls return 409 and the caller must create and apply a change request instead.
- Create a project.
- Create a project admin key.
- Create a client with metadata such as plan, country, or app version.
- Create a segment, for example
premium_users. - Create a flag with variants and optional prerequisites.
- Add environment rules for
stagingorproduction. - Create a client runtime key.
- Resolve runtime config or fetch a snapshot.
The API reference lives in openapi.yaml.
The Postman artifacts are:
- Root administrative access uses
FLAGIFY_BOOTSTRAP_KEY. - License: MIT
- This is a side project maintained primarily through agent-assisted iteration.