Amba

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:

interface SetConfigInput {
  key: string;
  value: unknown;
  value_type?: 'string' | 'number' | 'boolean' | 'json'; // default 'string'
  description?: string | null;
  conditions?: Array<
    { segment_id: string; value: unknown } | { percentage: number; value: unknown }
  >;
}

Example:

{
  "key": "daily_limit",
  "value": 10,
  "value_type": "number",
  "description": "Maximum daily actions"
}

Response 201:

{
  "data": {
    "key": "daily_limit",
    "value": 10,
    "value_type": "number",
    "conditions": [],
    "default_value": 10,
    "version": 1,
    "is_active": true,
    "updated_at": "..."
  }
}

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.

{ "data": [ { "key": "daily_limit", ... }, { "key": "feature_paywall_v2", ... } ] }

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:

{
  value?: unknown;
  description?: string | null;
  conditions?: Condition[];
}

404 if key doesn't exist.

DELETE /admin/config/:key

Hard delete. Bumps config_versions.version_hash so clients re-fetch.

{ "data": { "deleted": true } }

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:

{
  "data": {
    "daily_limit": 10,
    "feature_paywall_v2": false,
    "weekly_goal_count": 5
  },
  "etag": "<version_hash>"
}

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:

  1. For each entry in conditions:
    • If segment_id and the current user is in that segment → return value.
    • If percentage and the user's deterministic hash bucket is ≤ percentage → return value.
  2. If no condition matches → return default_value.

Conditions and default_value are server-side — the SDK only ever sees the resolved map.

Error codes

CodeHTTPWhen
NOT_FOUND404PATCH / GET on an unknown key
SET_FAILED500UPSERT or config_versions update failed
UPDATE_FAILED500PATCH failed
DELETE_FAILED500DELETE 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:

{ "segment_id": "seg_xxx", "value": <any> }
{ "percentage": 25, "value": <any> }

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

ToolDescription
amba_get_configRead a specific key for a project
amba_set_configCreate / update a key with optional conditions

Database tables

TablePurpose
remote_configsPer-key row: key, value, value_type, conditions, default_value
config_versionsSingle row: SHA-256 of all active configs, used as the ETag

Next

On this page