Remote Config API
Full Admin + Client API for remote config — request shapes, response shapes, conditions, and ETag semantics.
This page is the reference for the remote-config HTTP surface. For conceptual overview see Remote Config; for segment-based rollouts see Segment targeting.
Admin API
POST /admin/config
Create or upsert a config key. ON CONFLICT (key) DO UPDATE — the same call sets a new value or updates an existing one.
Request body:
Example:
Response 201:
Behavior:
- Updates are UPSERT — the same call creates or overwrites.
- Every successful mutation bumps
config_versions.version_hash(see ETag below).
GET /admin/config
List every active config for the project, ordered by key.
PATCH /admin/config/:key
Partial update. Only the fields you pass are changed. Passing value bumps the per-row version counter; passing only conditions or description does not (but still bumps config_versions.version_hash).
Request body:
404 if key doesn't exist.
DELETE /admin/config/:key
Hard delete. Bumps config_versions.version_hash so clients re-fetch.
Client API
GET /client/config
Returns the resolved config map (evaluated conditions + default values) plus an ETag. SDK handles this for you under client.config.get() / getAll().
Request headers:
X-Api-Key: <amb_..._ck_...>(required)Authorization: Bearer <session_token>(optional — needed for segment-gated values)If-None-Match: <etag>(optional, for cache revalidation)
Response:
If If-None-Match matches config_versions.version_hash, the server returns 304 Not Modified with no body — the SDK reuses its cached payload.
Resolution order
For each config key, the server evaluates conditions in order and returns the first match:
- For each entry in
conditions:- If
segment_idand the current user is in that segment → returnvalue. - If
percentageand the user's deterministic hash bucket is ≤percentage→ returnvalue.
- If
- If no condition matches → return
default_value.
Conditions and default_value are server-side — the SDK only ever sees the resolved map.
Error codes
| Code | HTTP | When |
|---|---|---|
NOT_FOUND | 404 | PATCH / GET on an unknown key |
SET_FAILED | 500 | UPSERT or config_versions update failed |
UPDATE_FAILED | 500 | PATCH failed |
DELETE_FAILED | 500 | DELETE failed |
ETag + version hash
config_versions is a singleton row (id = 1). Its version_hash is a SHA-256 of every active config's (key, value, version, conditions) tuple. Any mutation recomputes it under an advisory lock so concurrent updates can't race each other.
The SDK caches the resolved map plus the ETag. On refresh:
If-None-Match: <cached_etag>.- 200 → payload changed, replace cache.
- 304 → payload unchanged, bump timestamp.
Force a refresh with client.config.refresh() (bypasses the TTL but still sends the ETag).
Conditions JSON shape
Stored in remote_configs.conditions as a JSONB array. Each element is one of:
value_type is a hint for the admin UI — the server does not coerce values. Pass the same JSON shape for every condition and the default_value.
MCP tools
| Tool | Description |
|---|---|
amba_get_config | Read a specific key for a project |
amba_set_config | Create / update a key with optional conditions |
Database tables
| Table | Purpose |
|---|---|
remote_configs | Per-key row: key, value, value_type, conditions, default_value |
config_versions | Single row: SHA-256 of all active configs, used as the ETag |
Next
- Overview — SDK usage.
- Segment targeting — cohort-scoped values.