Two per-agent settings channels — runtime fields your flow scripts read, and front fields delivered to partner sites.
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.
Agents
The agent record itself — slug, run entry, active flag and lifecycle — lives on its own page.
{fieldId: value} map via system/settings. Saved on its own page and endpoint, separately from the agent details. Never delivered to partners.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: true/false, tracking whether runtime settings exist (front settings are not reflected). The settings themselves travel only on their dedicated settings endpoints.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
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.
| Type | Editor widget | Value |
|---|---|---|
input | Single-line text input (the default type) | string |
text | Textarea | string |
richtext | Rich-text editor | string — an untouched <p></p> counts as empty |
number | Number input | number — 0 is a real value |
password | Masked input | string |
boolean | Checkbox | boolean — false is a real value |
array | List of string items | string[] |
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.
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.'' 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.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.406 Not Acceptable with no detail attached — refusals are deliberately uniform so they never reveal whether a record exists or why it was refused.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.

The runtime settings editor — typed field rows your flow scripts read, with a validity badge and a live character counter.
N / 1,000,000 - allowed characters, which turns red over the limit.hasSettings value, scripts read the fresh valid rows through system/settings on their next run, and the r_agent webhook fires.hasSettings are untouched — then fires r_agent_front_settings so the partner site re-fetches the fresh values.
The partner-facing front settings editor — the same field-row builder, delivered to the partner's site.
valid stamp first — the editor blocks only new violations, so a saved set can carry invalid legacy rows that consumers skip.hasSettings flag, and it fires a different webhook kind — a partner watching only r_agent will never learn front settings changed.1,000,000-character cap you are.^[a-z][a-z0-9]*(-[a-z0-9]+)*$), while the agent's slug forbids them entirely.Keen Agents 2026
Documentation
Release 15