Evaluate flags

The POST/flags endpoint allows you to send a context object serialized as JSON and retrieve all flags at once for that context.

Evaluating a single context

The context object is a JSON object that can contain any key/value pairs you want.

JSON
cURL
Request body
{
  "userId": "foo",
  "email": "foo@gmail.com"
}

The response is a JSON object listing all flags and their corresponding values for that context:

Response
{
  "flagA": null,
  "flagC": "foo",
  "flagD": false
}
Warning

Since the value of a flag can be falsy, you must check if a key exists to determine if a flag exists or not. Checking the value may lead to false negatives.

Interpreting the response

Most of the time, checking if a key exists is enough, but if you want to do anything more complex than on / off, you might need to read the flag's value.

The above response can be interpreted as follows:

  • flagA has a value of null.
  • flagB is archived, deleted, or maybe it just does not exist. (It is simply not part of the response)
  • flagC has a value of "foo"
  • flagD has a value of false
Warning

You should never rely on whether or not a key is part of the response in your code. Always read the value of the flag with a hard coded default value if the key does not exist.

const response = {
  "flagA": false,
  "flagC": null,
}
 
if ('flagA' in response) { // ❌ Do not do this
  // Flag A might be in the response, but have a value of false
}
 
if (response.flagB) { // ❌ Do not do this
  // Flag B might not be in the response, implicitely the flag will be considered off
}
 
if (response.flagC ?? true) { // ❌ Do not do this
  // Flag C might be in the response, but have a value of null, unintentionnaly falling back to your default value
}
 
// ✅ Do this
const getFlagValue = (response, key, defaultValue) => {
  return key in response ? response[key] : defaultValue
}
 
if (getFlagValue(response, 'flagA', true)) {
  // Flag A is on, or the flag is not part of the response (default value true)
}

Evaluating flags in batches

On the backend you might need to evaluate a lot of contexts at once. Doing multiple HTTP requests will kill performance, you can instead pass an array of contexts in a single API call and get back an array of responses.

JSON
cURL
Request body
[
  { "userId": "foo", "email": "foo@gmail.com" },
  { "userId": null },
  { "userId": "baz" }
]

Contexts objects do not have to share the same keys. The response is an array of the same length:

Response
[
  {
    "flagA": null,
    "flagC": "foo",
    "flagD": false
  },
  {
    "flagC": "foo"
  },
  {
    "flagA": null,
    "flagD": true
  }
]

You can interpret the response the same way as before. Each response object corresponds to the context object at the same index.

Typed responses

For languages that are strongly typed, you can use the POST/typed-flags endpoint to retrieve the list of all flags for a list of contexts, with theire associated types.

JSON
cURL
Request body
[
  { "userId": "foo", "email": "foo@gmail.com" },
  { "userId": null },
  { "userId": "baz" }
]

Unlike the /flags endpoint, /typed-flags only accepts an array of contexts, to evaluate only a single context, pass an array of length 1.

Example
Schema
YAML
JSON
TypeScript
[
  [
    {
      "key": "my-feature",
      "type": "boolean",
      "booleanValue": true
    },
    {
      "key": "my-config",
      "type": "number",
      "numberValue": 42
    }
  ],
  [
    {
      "key": "my-feature",
      "type": "boolean",
      "booleanValue": false
    },
    {
      "key": "my-other-feature",
      "type": "null"
    }
  ],
  [
    {
      "key": "another-flag",
      "type": "json",
      "jsonValue": {
        "foo": "bar"
      }
    }
  ]
]

Error handling

If you API key is invalid or missing, you will receive a 401 Unauthorized response.

401 Unauthorized
{
  "error": "Invalid API key"
}

If the request body is invalid, you will receive a 400 Bad Request response.

400 Bad Request
{
  "error": "Unexpected end of JSON input"
}