Docs

Agent Settings

Two per-agent settings channels — runtime fields your flow scripts read, and front fields delivered to partner sites.

Two Channels per Agent

Independent channels, one shared editor.

Every agent carries two independent settings channels, each capped at 1,000,000 characters and stored separately from the agent record itself — so agent lists stay light no matter how large the settings grow. Runtime Agent Json Settings are custom fields your flow scripts read at run time through the system/settings resource. Front Agent Settings configure how the agent appears on the partner's site and are delivered to partner sites through the partner API. The two channels are strictly isolated in both directions: partners never see runtime settings, and scripts never see front settings.

Both channels are edited with the same JSONForm editor — a builder of typed field rows that produces a validated JSON array. Consumers only ever receive rows that passed validation.

1,000,000-char cap per channelstrict two-way isolationvalid rows only reach consumersdedicated save endpoints

Agents

The agent record itself — slug, run entry, active flag and lifecycle — lives on its own page.

The Two Channels

Runtime channel
Agent Json Settings. Flow scripts receive the valid rows only as a flat {fieldId: value} map via system/settings. Saved on its own page and endpoint, separately from the agent details. Never delivered to partners.
Front channel
Front Agent Settings, with the same cap. Partner sites fetch them through the partner API's agent front-settings endpoint, and each partner can only read agents in the spaces its contract includes — tenant isolation is enforced on every fetch. Never exposed to scripts. A front save touches neither the agent record nor the runtime settings.
The valid stamp
Every row is stamped valid true/false by the editor's validation pass. The stamp is derived output — re-computed on every load, never trusted as input — and consumers skip rows stamped false. An operator can save a partially-invalid legacy set without invalid rows ever reaching a script or a partner.
hasSettings
Agent list responses never carry a settings payload — only hasSettings: true/false, tracking whether runtime settings exist (front settings are not reflected). The settings themselves travel only on their dedicated settings endpoints.
Settings webhooks
Notify-then-fetch: every save POSTs a small notification to each webhook URL your organization configured. Your endpoint has five seconds to answer; failures are never retried or surfaced, so treat the notification as a nudge to re-fetch, not as the data itself. A runtime save fires the r_agent kind; a front save fires its own r_agent_front_settings kind, prompting the partner site to re-fetch the fresh values.

webhook kinds

POST <your webhook URL>                         (notification only — fetch the fresh values afterwards)

{"synch-data": ["r_agent"]}                     ← runtime-settings save (also agent create/update/delete)
{"synch-data": ["r_agent_front_settings"]}      ← front-settings save ONLY

Field Rows & Types

Both channels store a JSON array of typed rows.

A row is { displayName, fieldId, fieldType, required, value, valid }. The fieldId follows the kebab-case pattern ^[a-z][a-z0-9]*(-[a-z0-9]+)*$ — digits are allowed here, unlike the agent's slug — and must be unique within the set (the first occurrence wins, later duplicates are flagged). displayName needs at least 1 character; required defaults to false.

TypeEditor widgetValue
inputSingle-line text input (the default type)string
textTextareastring
richtextRich-text editorstring — an untouched <p></p> counts as empty
numberNumber inputnumber — 0 is a real value
passwordMasked inputstring
booleanCheckboxboolean — false is a real value
arrayList of string itemsstring[]

Required is type-relative: a required field with a type-relative empty value is an error, but 0 and false pass — only genuinely blank values fail.

Rules & Limits

  • Each channel holds at most 1,000,000 characters. The limit is enforced end to end — the editor's live counter, the save itself, and storage all agree — so a save the editor accepts is never refused later for size.
  • An empty string '' is a legitimate save — it clears the settings. KeenAgents distinguishes "agent exists with no settings" from "unknown agent", so clearing never makes the agent look deleted.
  • The general agent update can never change settings — any settings value included in it is ignored. The dedicated PATCH /agents/:id/settings and PATCH /agents/:id/front-settings endpoints are the only settings writers, so an agent-record edit can never clobber a settings save.
  • fieldType must be one of input | text | richtext | number | password | boolean | array; the value carries the matching type.
  • Deleting an agent deletes both of its settings channels automatically; deleting a space deletes its agents and their settings — no orphaned state, no undo.
  • Every failed operation returns a generic 406 Not Acceptable with no detail attached — refusals are deliberately uniform so they never reveal whether a record exists or why it was refused.

Editing in the Admin UI

Both channels share one settings card — same editor, different copy.

The runtime editor lives at /agents/<id>/json-settings, the partner editor at /agents/<id>/front-settings (its card reads "Delivered to partner sites — never exposed to scripts."). Rows render as read-only summaries; all editing happens in two modals.

Agent runtime (JSON) settings editor

The runtime settings editor — typed field rows your flow scripts read, with a validity badge and a live character counter.

  1. + Add Field (rendered next to Update Settings) opens the Definition modal: Display Name, Field ID, Type, Required. Save stays disabled until valid; the Field ID auto-kebabs as you type and is checked live for uniqueness.
  2. Set Value opens a value modal whose input widget matches the row's type — a checkbox for boolean, a rich-text editor for richtext, and so on.
  3. Watch the header badges: a valid/invalid stamp and a live character counter shown as N / 1,000,000 - allowed characters, which turns red over the limit.
  4. Update Settings is enabled only when the set is valid, under the limit, and actually changed from the load-time baseline. Saves are validated once more before the request leaves the browser; server errors render inline on the card.
  5. A runtime save takes effect immediately: agent lists reflect the new hasSettings value, scripts read the fresh valid rows through system/settings on their next run, and the r_agent webhook fires.
  6. A front save changes the front channel only — the agent record, the runtime settings and hasSettings are untouched — then fires r_agent_front_settings so the partner site re-fetches the fresh values.
Agent partner-facing front settings editor

The partner-facing front settings editor — the same field-row builder, delivered to the partner's site.

Changing a row's type resets its value
Switching a field row's type in the Definition modal resets that row's value to the new type's blank — the modal shows a warning before you commit.

Good to Know

  • A value on the wrong surface is silently invisible to its intended consumer: a runtime field never reaches the partner site, and a front field is unreachable from scripts. Pick the channel by who must read it.
  • If a field "isn't showing up" at run time, check its row's valid stamp first — the editor blocks only new violations, so a saved set can carry invalid legacy rows that consumers skip.
  • A front save changes neither the agent record nor the hasSettings flag, and it fires a different webhook kind — a partner watching only r_agent will never learn front settings changed.
  • Renaming the agent's slug carries both settings channels along — nothing is lost — but external callers still pointing at the old slug must be updated by hand.
  • If a save is refused at the limit, the counter badge on the settings card shows exactly how far over the 1,000,000-character cap you are.
  • The two kebab-case rules are similar but not identical: settings field ids allow digits (^[a-z][a-z0-9]*(-[a-z0-9]+)*$), while the agent's slug forbids them entirely.

Previous

Agents

Next

Flows & Runtime

Keen Agents 2026

Documentation

Release 15