Cheat sheet
This cheat sheet provides quick reference examples for running flagd and evaluating flags using various protocols and configurations.
Recommended tools:
Tip
These commands assume a unix-like shell.
Output is generally JSON, and can be pretty-printed by piping into jq (ie: curl ... | jq)
Protocols and tabs
flagd exposes the same functionality over multiple protocols, so the examples below are tabbed. Not every operation supports every protocol. Streaming methods use native gRPC or Connect streaming over HTTP; OFREP exposes REST evaluation.
- HTTP (REST) - plain
curlagainst OFREP (evaluation) orGET /v1/flags(sync). The simplest path. - HTTP (Connect) - the gRPC service methods as HTTP/JSON via the Connect protocol; plain
curlwithContent-Type: application/json, no gRPC client required. - gRPC (grpcurl) - the native gRPC services, using grpcurl (needs the proto files, see below).
Sample Flag Definitions
The examples below use these sample flag definition files. Download them to follow along:
- cheat-sheet-flags.json - General application flags (flagSetId:
app-flags) - cheat-sheet-flags-payments.json - Payment-related flags (flagSetId:
payment-flags)
The app-flags set includes:
| Flag Key | Type | Description |
|---|---|---|
simple-boolean |
boolean | Static boolean flag |
simple-string |
string | Static string flag |
simple-number |
integer | Static numeric flag |
simple-object |
object | Static object flag |
user-tier-flag |
string | Context-sensitive flag based on tier |
email-based-feature |
boolean | Context-sensitive flag based on email domain |
region-config |
object | Context-sensitive flag based on region |
The payment-flags set includes:
| Flag Key | Type | Description |
|---|---|---|
payment-provider |
string | Static payment provider selection |
max-transaction-amount |
integer | Context-sensitive based on account-verified |
enable-crypto-payments |
boolean | Context-sensitive based on country |
Running flagd
# Single flag source (local file)
docker run --rm -it \
-p 8013:8013 \
-p 8015:8015 \
-p 8016:8016 \
-v $(pwd):/flags \
ghcr.io/open-feature/flagd:latest start \
--uri file:./flags/cheat-sheet-flags.json
Note
The remaining examples use Docker, but all CLI flags work identically with the binary.
Default ports
| Port | Protocol | Service |
|---|---|---|
| 8013 | gRPC + HTTP | Flag evaluation (evaluation.proto, also served as HTTP/JSON via Connect) |
| 8014 | HTTP | Management (health checks, metrics) |
| 8015 | gRPC + HTTP | Flag sync (sync.proto, also served as HTTP/JSON via Connect and GET /v1/flags) |
| 8016 | HTTP | OFREP (OpenFeature Remote Evaluation Protocol) |
Proto files for grpcurl
flagd does not support gRPC reflection, so grpcurl needs the proto files to serialize requests and responses.
Clone the schemas repo (or download the protos from buf.build/open-feature/flagd) and point $PROTO_DIR at them:
Evaluating flags
Evaluate a single flag
Evaluate different flag types
Each type has its own method. Note ResolveInt encodes the value as a JSON string ("50"), per proto3 JSON:
# String flag
curl -X POST 'http://localhost:8013/flagd.evaluation.v2.Service/ResolveString' \
-H 'Content-Type: application/json' \
-d '{"flagKey": "simple-string", "context": {}}'
# Number flag (ResolveInt or ResolveFloat)
curl -X POST 'http://localhost:8013/flagd.evaluation.v2.Service/ResolveInt' \
-H 'Content-Type: application/json' \
-d '{"flagKey": "simple-number", "context": {}}'
# Object flag
curl -X POST 'http://localhost:8013/flagd.evaluation.v2.Service/ResolveObject' \
-H 'Content-Type: application/json' \
-d '{"flagKey": "simple-object", "context": {}}'
# String flag
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/evaluation/v2/evaluation.proto \
-d '{"flagKey": "simple-string", "context": {}}' \
localhost:8013 \
flagd.evaluation.v2.Service/ResolveString
# Number flag (ResolveInt or ResolveFloat)
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/evaluation/v2/evaluation.proto \
-d '{"flagKey": "simple-number", "context": {}}' \
localhost:8013 \
flagd.evaluation.v2.Service/ResolveInt
# Object flag
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/evaluation/v2/evaluation.proto \
-d '{"flagKey": "simple-object", "context": {}}' \
localhost:8013 \
flagd.evaluation.v2.Service/ResolveObject
Evaluate all flags
OFREP bulk evaluation returns every flag in one response:
Response:
{
"flags": [
{"key": "simple-boolean", "reason": "STATIC", "variant": "on", "value": true, "metadata": {}},
{"key": "simple-string", "reason": "STATIC", "variant": "greeting", "value": "Hello, World!", "metadata": {}},
{"key": "simple-number", "reason": "STATIC", "variant": "medium", "value": 50, "metadata": {}}
]
}
ResolveAll lives in the v1 evaluation service:
Context-Aware Evaluation
Context from Request Body
Pass evaluation context in the request body to trigger targeting rules:
# Evaluate with email context (triggers email-based-feature targeting)
curl -X POST 'http://localhost:8016/ofrep/v1/evaluate/flags/email-based-feature' \
-H 'Content-Type: application/json' \
-d '{"context": {"email": "user@example.com"}}'
Response (email matches @example.com):
{
"key": "email-based-feature",
"reason": "TARGETING_MATCH",
"variant": "on",
"value": true,
"metadata": {}
}
# Evaluate with email context (triggers email-based-feature targeting)
curl -X POST 'http://localhost:8013/flagd.evaluation.v2.Service/ResolveBoolean' \
-H 'Content-Type: application/json' \
-d '{"flagKey": "email-based-feature", "context": {"email": "user@example.com"}}'
# Evaluate with tier context
curl -X POST 'http://localhost:8013/flagd.evaluation.v2.Service/ResolveString' \
-H 'Content-Type: application/json' \
-d '{"flagKey": "user-tier-flag", "context": {"tier": "premium"}}'
# Evaluate with email context (triggers email-based-feature targeting)
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/evaluation/v2/evaluation.proto \
-d '{"flagKey": "email-based-feature", "context": {"email": "user@example.com"}}' \
localhost:8013 \
flagd.evaluation.v2.Service/ResolveBoolean
# Evaluate with tier context
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/evaluation/v2/evaluation.proto \
-d '{"flagKey": "user-tier-flag", "context": {"tier": "premium"}}' \
localhost:8013 \
flagd.evaluation.v2.Service/ResolveString
Context from Static Values
Add static context values using the -X flag at startup. These are automatically included in all evaluations:
docker run --rm -it \
-p 8013:8013 -p 8015:8015 -p 8016:8016 \
-v $(pwd):/flags \
ghcr.io/open-feature/flagd:latest start \
--uri file:./flags/cheat-sheet-flags.json \
-X region=eu \
-X environment=production
# region=eu and environment=production is automatically applied without needing to send context
curl -X POST 'http://localhost:8016/ofrep/v1/evaluate/flags/region-config'
Context from HTTP Headers
Map HTTP headers to evaluation context keys using the -H flag at startup:
docker run --rm -it \
-p 8013:8013 -p 8015:8015 -p 8016:8016 \
-v $(pwd):/flags \
ghcr.io/open-feature/flagd:latest start \
--uri file:./flags/cheat-sheet-flags.json \
-H "X-User-Tier=tier" \
-H "X-User-Email=email"
Now context is extracted from request headers:
# tier context comes from X-User-Tier header
curl -X POST 'http://localhost:8016/ofrep/v1/evaluate/flags/user-tier-flag' \
-H 'X-User-Tier: enterprise'
# email context comes from X-User-Email header
curl -X POST 'http://localhost:8016/ofrep/v1/evaluate/flags/email-based-feature' \
-H 'X-User-Email: developer@example.com'
Context Priority
When using multiple context sources, values are merged with this priority (highest to lowest):
- Header-mapped context values (
-Hflag) - Static context values (
-Xflag) - Request body context
Using the Selector Header
When using multiple flag sources, the Flagd-Selector header restricts which flags are evaluated.
Start flagd with multiple sources:
docker run --rm -it \
-p 8013:8013 -p 8015:8015 -p 8016:8016 \
-v $(pwd):/flags \
ghcr.io/open-feature/flagd:latest start \
--uri file:./flags/cheat-sheet-flags.json \
--uri file:./flags/cheat-sheet-flags-payments.json
Filter evaluations by flag set (flagSetId):
# Evaluate only flags from the app flag set
curl -X POST 'http://localhost:8016/ofrep/v1/evaluate/flags' \
-H 'Flagd-Selector: flagSetId=app-flags'
# Evaluate only flags from the payments flag set
curl -X POST 'http://localhost:8016/ofrep/v1/evaluate/flags' \
-H 'Flagd-Selector: flagSetId=payment-flags'
# Single flag evaluation with selector
curl -X POST 'http://localhost:8016/ofrep/v1/evaluate/flags/payment-provider' \
-H 'Flagd-Selector: flagSetId=payment-flags'
# Single flag evaluation with selector
curl -X POST 'http://localhost:8013/flagd.evaluation.v2.Service/ResolveBoolean' \
-H 'Content-Type: application/json' \
-H 'Flagd-Selector: flagSetId=app-flags' \
-d '{"flagKey": "simple-boolean", "context": {}}'
# ResolveAll with selector
curl -X POST 'http://localhost:8013/flagd.evaluation.v1.Service/ResolveAll' \
-H 'Content-Type: application/json' \
-H 'Flagd-Selector: flagSetId=payment-flags' \
-d '{"context": {}}'
# Single flag evaluation with selector
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/evaluation/v2/evaluation.proto \
-H 'Flagd-Selector: flagSetId=app-flags' \
-d '{"flagKey": "simple-boolean", "context": {}}' \
localhost:8013 \
flagd.evaluation.v2.Service/ResolveBoolean
# ResolveAll with selector
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/evaluation/v1/evaluation.proto \
-H 'Flagd-Selector: flagSetId=payment-flags' \
-d '{"context": {}}' \
localhost:8013 \
flagd.evaluation.v1.Service/ResolveAll
Event Stream
The EventStream is a server stream that pushes configuration_change events when flags change (used by RPC-mode providers for cache invalidation).
It is a streaming method; over HTTP it is available as Connect streaming, but grpcurl is the practical CLI:
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/evaluation/v1/evaluation.proto \
-d '{}' \
localhost:8013 \
flagd.evaluation.v1.Service/EventStream
The Flagd-Selector header also filters the stream, so it only reports configuration_change events for flags in the selected flag set(s):
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/evaluation/v1/evaluation.proto \
-H 'Flagd-Selector: flagSetId=payment-flags' \
-d '{}' \
localhost:8013 \
flagd.evaluation.v1.Service/EventStream
For the EventStream, the selector can only be supplied via the header; its request body has no selector field.
Syncing Flag Configuration
The sync service (port 8015) is used by in-process providers to fetch and stream flag configurations.
It serves the gRPC sync.proto service and, on the same port, an HTTP GET /v1/flags endpoint (the unary equivalent of FetchAllFlags).
Disable the HTTP endpoint with --sync-http-enabled=false.
Fetch all flags
GET /v1/flags returns the flag configuration document itself (the same string FetchAllFlags returns in its flag_configuration field):
Response:
Fetch all flags with a selector
Filter which flag source's configuration is returned.
The selector is supplied with the Flagd-Selector header:
# Fetch only the payment flags
curl -H 'Flagd-Selector: flagSetId=payment-flags' http://localhost:8015/v1/flags
The endpoint distinguishes two outcomes:
| Result | Example | Status |
|---|---|---|
| Selector is malformed or names an unknown filter | control characters, bogus=1 |
400 |
| Valid filter that currently matches no flags | flagSetId=empty-set |
200 with {"flags":{}} |
An empty result is deliberately not an error: a flag set holding no flags is a normal state, and a downstream flagd syncing from this endpoint should not break when it happens.
The selector may be supplied in the request body or with the Flagd-Selector header; if both are present, the header wins:
# Fetch only the app flags
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/sync/v1/sync.proto \
-d '{"selector": "flagSetId=app-flags"}' \
localhost:8015 \
flagd.sync.v1.FlagSyncService/FetchAllFlags
# With provider ID for identification
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/sync/v1/sync.proto \
-d '{"providerId": "my-app-sidecar", "selector": "flagSetId=app-flags"}' \
localhost:8015 \
flagd.sync.v1.FlagSyncService/FetchAllFlags
The Flagd-Selector header works as an alternative to the request body selector field; if both are supplied, the header takes precedence.
Streaming sync
SyncFlags establishes a server-streaming connection that pushes the initial configuration and then streams updates whenever flags change.
Like EventStream it is a streaming method (Connect streaming over HTTP, or native gRPC); grpcurl is the practical CLI:
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/sync/v1/sync.proto \
-d '{}' \
localhost:8015 \
flagd.sync.v1.FlagSyncService/SyncFlags
# Stream the app flags (initial config, then updates as they change)
grpcurl -plaintext \
-import-path "$PROTO_DIR" -proto flagd/sync/v1/sync.proto \
-d '{"selector": "flagSetId=app-flags"}' \
localhost:8015 \
flagd.sync.v1.FlagSyncService/SyncFlags
HTTP caching
GET /v1/flags responses carry both validators, so pollers can revalidate cheaply:
ETagis computed from the response body, so it is exact for the requested selector.Last-Modifiedis the last time flagd observed a change to any flag configuration, so it is conservative; it may cost a request a304it could have had, but never serves a stale one.
If-None-Match and If-Modified-Since are both honored, with If-None-Match taking precedence when both are sent:
Chaining flagd instances
Because GET /v1/flags returns an ordinary flag configuration document, another flagd instance can consume it directly as an HTTP sync source:
To sync only a subset, set the selector header on the source, which needs the --sources form:
flagd start --sources='[{"uri":"http://localhost:8015/v1/flags","provider":"http","headers":{"Flagd-Selector":"flagSetId=payment-flags"}}]'
Quick Reference
Ports
| Port | Protocol | Service | Description |
|---|---|---|---|
| 8013 | gRPC / HTTP | Evaluation | Flag evaluation API (evaluation.proto, also HTTP/JSON via Connect) |
| 8014 | HTTP | Management | Health checks, metrics |
| 8015 | gRPC / HTTP | Sync | Flag sync (sync.proto, also HTTP/JSON via Connect and GET /v1/flags) |
| 8016 | HTTP | OFREP | OpenFeature Remote Evaluation Protocol |
Health Check
See Also
- Flag Definitions - Complete flag definition reference
- OFREP Service - OFREP API details
- gRPC Sync Service - Sync service details
- Sync Configuration - Configure flag sources
- CLI Reference - Complete CLI options