Retrieve feature flags with API
The Evaluation Server offers two APIs that allow you to retrieve feature flags for both client-side and server-side sdks, specific to the desired environment.
The differences between client side and server side SDKs are:
- Client side SDK is for single user but Server side SDK is for multiple users
- Client side SDK relies on the Evaluation Server to evaluate all the flags while Server Side SDK evaluates the flags locally
Please note that you need to replace {Host} in the API requests with the appropriate host URL for your environment. {Host} can be the evaluation server host or the FeatBit Agent host, both of them provide the same API.
Polling With Timestamp Parameter
Both APIs support an optional timestamp query parameter that enables efficient polling for feature flag updates. When provided, the server will only return flags that have been modified after the specified timestamp. This helps reduce bandwidth and processing overhead by avoiding unnecessary data transfers when flags haven't changed.
How it works:
- Make an initial request without the
timestampparameter to get all feature flags - Store the max
timestampvalue from the response - In subsequent polling requests, include the stored timestamp as a query parameter:
?timestamp={value} - The server will only return flags modified after that timestamp
- Update your stored timestamp with the latest value from each response
Where to read the timestamp from:
- Client-side requests: Extract the
timestampfield from each feature flag object in thedata.featureFlagsarray. Take the maximum value from all timestamps. - Server-side requests: Extract the
updatedAtfield from all objects in both thedata.featureFlagsanddata.segmentsarrays. Find the latest among them and convert it to milliseconds.
Benefits:
- Reduced network bandwidth usage
- Lower server load
- Faster response times when no changes have occurred
Client Side
For client-side requests, provide the client environment secret in the Authorization header.
Request
# Initial request (no timestamp)
curl -X POST {Host}/api/public/sdk/client/latest-all \
-H 'Content-Type: application/json' \
-H 'Authorization: client-env-secret' \
-d '{
"keyId": "bot-id",
"name": "bot",
"customizedProperties": [
{
"name": "level",
"value": "high"
},
{
"name": "location",
"value": "us"
}
]
}'
# Subsequent polling request (with timestamp in milliseconds)
curl -X POST '{Host}/api/public/sdk/client/latest-all?timestamp=1712755780494' \
-H 'Content-Type: application/json' \
-H 'Authorization: client-env-secret' \
-d '{
"keyId": "bot-id",
"name": "bot",
"customizedProperties": [
{
"name": "level",
"value": "high"
},
{
"name": "location",
"value": "us"
}
]
}'Response
{
"messageType":"data-sync",
"data":{
"eventType":"full",
"userKeyId":"bot-id",
"featureFlags":[
{
"id":"hello-world",
"variation":"false",
"variationType":"boolean",
"variationId":"3f02a597-a150-4c3f-83b9-27a2de80c7dc",
"matchReason":"flag disabled",
"variationOptions":[
{
"id":"fafb6319-9270-4a4b-b2c3-12d2be29e69a",
"value":"true"
},
{
"id":"3f02a597-a150-4c3f-83b9-27a2de80c7dc",
"value":"false"
}
],
"sendToExperiment":false,
"timestamp":1712755780494
}
]
}
}Server Side
For server-side requests, provide the server environment secret in the Authorization header.
Request
# Initial request (no timestamp)
curl -H "Authorization: server-env-secret" {Host}/api/public/sdk/server/latest-all
# Subsequent polling request (with timestamp in milliseconds)
curl -H "Authorization: server-env-secret" '{Host}/api/public/sdk/server/latest-all?timestamp=1712755780494'Response
{
"messageType":"data-sync",
"data":{
"eventType":"full",
"featureFlags":[
{
"envId":"1331554d-98c4-41fe-ade4-68e6f5eeb54a",
"name":"hello world",
"key":"hello-world",
"variationType":"boolean",
"variations":[
{
"id":"bbe8f444-090e-4a3b-99fa-b487bab424aa",
"value":"true"
},
{
"id":"cf8f9626-0d6f-4d05-a98f-8c3a50c85d0f",
"value":"false"
}
],
"targetUsers":[
],
"rules":[
],
"isEnabled":true,
"disabledVariationId":"cf8f9626-0d6f-4d05-a98f-8c3a50c85d0f",
"fallthrough":{
"dispatchKey":null,
"includedInExpt":true,
"variations":[
{
"id":"bbe8f444-090e-4a3b-99fa-b487bab424aa",
"rollout":[
0,
1
],
"exptRollout":1
}
]
},
"exptIncludeAllTargets":true,
"tags":[
],
"isArchived":false,
"disabledVariation":{
"id":"cf8f9626-0d6f-4d05-a98f-8c3a50c85d0f",
"value":"false"
},
"creatorId":"b58fa8fd-eca2-460a-ab0f-e7758dbcec6a",
"updatorId":"b58fa8fd-eca2-460a-ab0f-e7758dbcec6a",
"createdAt":"2023-03-16T09:11:23.739Z",
"updatedAt":"2023-03-16T09:11:26.0465535Z",
"id":"4daca70f-86ae-4468-aee8-afc700977202"
}
],
"segments":[
{
"envId":"1331554d-98c4-41fe-ade4-68e6f5eeb54a",
"name":"beta users",
"description":"this is a segment for beta users",
"included":[
],
"excluded":[
],
"rules":[
],
"isArchived":false,
"createdAt":"2023-03-16T09:18:21.1317917Z",
"updatedAt":"2023-03-16T09:18:21.1317248Z",
"id":"b2b91bbe-5d54-4d8a-882f-afc700995b23"
}
]
}
}