SET any single-value config section durably (1.5.0 full-config coverage): partial RootSettings merged onto the overlay, re-resolved + validated, swapped in. rate_card/per_request_fee/security/limits/… go live; listen/tls/admin_listen/admin_tls/admin_require_mtls/store are stored + flagged restart-to-apply (bound once at start / store reused across a hot reload). NEVER writes config.yaml

Changed on
put/api/v1/admin/config/settings

Request

  • The document declares no server URL.
  • Auth: one of:
    • API key in header x-admin-token
    • HTTP bearer

Headers

If-Matchstring

Optimistic concurrency: the resource's ETag from a prior read (or the ETag returned by the previous mutation). Stale = 409 version_conflict (re-read and retry), nothing changes; absent or * = unconditional.

Request body

object required

The settings sections to replace, keyed by section name. Durable by default (1.5.3): a mutable config always stores the change in its overlay (survives restart), and a locked config (config.locked: true) refuses ANY change with 400. There is no "apply in memory only" outcome. The optional top-level boolean persist is accepted for back-compat and boolean-validated (a non-boolean is a 400 naming the field), but its value has NO effect: persistence is unconditional on a mutable config and refusal is unconditional on a locked one. Every other top-level key must be a known settings section; an unknown key is a 400. The accepted shape is the config file's own, documented in the configuration reference; it is not restated here because several of its types parse a wire shape that does not match their field layout.

Response

{applied:true, config_version, settings, reload_to_apply, note}

appliedboolean required

true on a PUT that stored + swapped; false on a GET (a pure read).

config_versioninteger required
notestring nullable

A human note describing the live-vs-reload split (absent on a GET).

reload_to_applystring[]

Fields that were stored durably but are RESTART-TO-APPLY: a socket rebind, a TLS acceptor build and a store open all happen once at process start, so a POST /config/reload does NOT make them live; POST /restart (or a supervisor restart) does. Empty when the PUT touched only live-swappable fields (or on a GET). The field NAME is frozen wire; only this description changed.

settingsunknown required

Changes