Amba

Config

Remote config for the app — evaluated for the signed-in user, typed and ETag-aware.

/client/config returns the project's active remote config keys. It takes the client key and reads the session token when the request carries one. For a signed-in user (a valid session token, or a server key with X-On-Behalf-Of) the route evaluates each key's conditions in order and returns the value of the first one that matches; every other caller, including one whose session token has expired, gets each key's default value. Responses are cacheable via ETag / If-None-Match; cache control is private (max-age=60 for a signed-in user, max-age=300 otherwise) to prevent multi-tenant leakage through shared proxies.

Endpoints

MethodPathDescription
GET/client/configConfig map, evaluated for the signed-in user. Takes X-Api-Key.

GET /client/config

Request

GET /client/config
X-Api-Key: amb_dev_ck_xxx
Authorization: Bearer <session_token>    (optional; applies the key's conditions for this user)
If-None-Match: "<prior-etag>"            (optional)

Response 200

{
  "data": {
    "my_feature_flag": true,
    "paywall_price": 9.99,
    "promo_copy": { "headline": "Spring sale", "discount": 0.2 }
  }
}

Each value comes back as its declared type — a boolean is a JSON true/false, a number is a JSON number, and a json config is a parsed object/array. You don't parse or cast on the client; config.promo_copy.headline works directly.

Typed values

Every config carries a value_type of string, number, boolean, or json, set when the config is authored. The server coerces the resolved value to that declared type before it serializes the response, so a value authored as a string of JSON (a common mistake) still arrives as the right type — no client release required. Coercion is forgiving: a value that's already the right shape passes through untouched, and a value that can't be coerced (malformed JSON, a non-numeric string typed as number) is returned as-is rather than failing the whole fetch.

value_typeYou receive
stringA JSON string.
numberA JSON number.
booleanA JSON true / false.
jsonA parsed object / array / any value.

Headers:

ETag: "<version_hash>"                       (signed out)
ETag: "<version_hash>:<user_id>:<segments>"   (signed in)
Cache-Control: private, max-age=300           (signed out; max-age=60 signed in)
Vary: Authorization, X-On-Behalf-Of

Response 304

Returned when If-None-Match matches the current ETag. The body is empty.

ETag composition

The ETag is "<version_hash>", the project's config_versions.version_hash. It changes whenever a config key is created, updated, or deleted.

Stored conditions

A config can carry a conditions array, set through the admin API or amba_remote_configs_create. Each entry has an optional segment_id, an optional percentage (0–100), and a value:

{
  "key": "paywall_price",
  "value_type": "number",
  "default_value": 9.99,
  "conditions": [
    { "segment_id": "<whales-segment-id>", "value": 14.99 },
    { "percentage": 10, "value": 4.99 }
  ]
}

The admin API stores and returns conditions. For a signed-in user, GET /client/config walks them in order: a condition applies when the user is in its segment_id (if it has one) and inside its percentage (if it has one), and the first that applies supplies the value. A user no condition matches, and every caller without a session, gets default_value. A user's percentage bucket is stable per key, so the same user keeps the same answer.

Errors

  • 500 FETCH_FAILED.

Try it:

GET/client/config
public auth
curl -X GET 'https://api.amba.dev/v1/client/config'
Loading auth… Configure auth in the settings drawer (top-right) to run this request.

Curl:

curl -X GET "${BASE_URL}/client/config" \
  -H "X-Api-Key: ${CLIENT_API_KEY}"

On this page