Feature flagsSDKsWithout an SDKcode
Without an SDK
The endpoint every SDK wraps, both credential forms, and what each reason means.
What you'll have
Flags read over plain HTTP, from any language.
Every SDK is a wrapper over one endpoint, so anything that can post JSON can read flags.
From a server
Authenticate with the API key:
curl -X POST "$VARIABLY_BASE_URL/api/v1/sdk/evaluate/all" \
-H "Content-Type: application/json" \
-H "X-API-Key: $VARIABLY_API_KEY" \
-d '{"context": {"userId": "user-123"}}'
From a browser
Authenticate with the client-side ID, in the query string:
curl -X POST "$VARIABLY_BASE_URL/api/v1/sdk/evaluate/all?clientSideId=$CLIENT_SIDE_ID" \
-H "Content-Type: application/json" \
-d '{"context": {"userId": "user-123"}}'
It goes in the query string rather than a header on purpose. A custom request header is not
CORS-safelisted, so it forces a preflight — and that preflight is answered by whatever CDN sits in
front of the API, against an allow-list your application cannot change. The query string needs no
preflight beyond Content-Type.
Other endpoints
| Endpoint | Returns |
|---|---|
POST /api/v1/sdk/evaluate/all | Every flag the credential may read |
POST /api/v1/sdk/evaluate | One flag |
POST /api/v1/sdk/evaluate/batch | The flags you name |
The response
{
"flags": {
"checkoutRedesign": { "flag_key": "checkoutRedesign", "value": true, "reason": "flag_enabled" }
}
}
reason is worth reading while integrating — each value points at a different fix.
| Reason | Means |
|---|---|
flag_enabled | The flag is on. |
gate_disabled | The flag is off, and you are seeing its Default value. |
gate_not_found | No such gate key for this credential. Check the spelling, and whether the gate is hidden from client-side SDKs. |