Job & Dashboard Reference
job_config schema
Reference the job_config schema: form and field_mapping entries, every field and option source key, snapshots, and the config API.
job_config schema
job_config is a runtime-editable configuration schema declared at the top level of a job template and copied onto every Job created from it. Operators edit the values from the Job Details page after the Job exists; tasks read them in JSONata as job_config.<key>; every run snapshots the current values onto runs.job_config. The schema is parsed by parseJobConfigSchema in src/job-config-schema.ts, which reuses the dashboard input-widget shapes.
It differs from arguments: arguments are create-time values fixed once the Job exists, while job_config stays editable and each Job can diverge from its template. See Job config: forms and field mapping for the authoring guide.
Entry keys
Each top-level key becomes the stored config key and the JSONata key:
job_config:
migration_step: # read as job_config.migration_step.stage
type: form
title: Migration stage
fields:
- key: stage
type: select
required: true
default: connect_accounts
options:
- { label: Connect accounts, value: connect_accounts }
- { label: Migrate tickets, value: migrate_tickets }- Keys must match
^[A-Za-z0-9_-]+$— letters, numbers, underscores, or hyphens — and must be non-empty. typemust beformorfield_mapping; any other widget type is rejected withjob_config.<key>.type must be "form" or "field_mapping".- Do not put
idorconfig_keyinside an entry — the parser supplies both from the map key.
form
Stores an object keyed by field key (for example job_config.migration_step.stage).
| Field | Type | Required | Description |
|---|---|---|---|
fields |
array | Yes | Non-empty array of form fields (see below). |
title |
string | No | Display title. |
description |
string | No | Display description. |
validation_expr |
string | No | JSONata run against the value before persisting; a non-empty result rejects the save. |
transform_expr |
string | No | JSONata that reshapes the value just before it is written. |
Form fields
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Key the field's value is stored under. |
label |
string | No | Display label. |
type |
string | Yes | text, number, boolean, select, or multi_select. |
required |
boolean | No | Value must be present on save. |
default |
any | No | Seeds the Job's initial value. |
format |
string | No | email or url — validated on save. |
options |
array | No | Inline choices; each entry is { label, value } and label is required. |
options_source |
object | No | Connector-backed choices (see Option sources). |
depends_on |
string[] | No | Sibling field keys; options refetch and the value resets when a dependency changes. |
hide_if_expr |
string | No | JSONata; hides the field when it evaluates truthy. |
Option sources
select and multi_select fields, and each field_mapping side, can load options through a read-only connector call. Options resolve one page at a time as { options, next_cursor } — the iterator is never drained.
options_source:
connector: hubspot
method: proxy_list
args: { resource: pipelines }
label_expr: $.label
value_expr: $.id
search:
param: q| Field | Required | Description |
|---|---|---|
options_source |
Yes | { connector, method, args? }, or a JSONata string resolving to one. Must be a read-only method. |
label_expr |
No | JSONata per row → option label. |
value_expr |
No | JSONata per row → option value. |
subtext_expr |
No | JSONata per row → optional secondary text. |
search.param |
Yes, when search is set |
Argument name the search string is injected into. |
search.on_frontend |
No | true fetches one bounded page and filters in the UI; use only for single-call lists. |
search.placeholder / search.empty_text |
No | UI strings. |
transform_expr |
No | JSONata applied to the raw response before row mapping. |
depends_on |
No | string[] of sibling keys that trigger a refetch. |
field_mapping
Stores an array of { source_field, target_field, transform? } rows.
job_config:
ticket_field_map:
type: field_mapping
title: Ticket field mapping
default:
- { source_field: subject, target_field: title }
source:
options_source:
connector: zendesk
method: proxy_list
args: { resource: ticket_fields }
label_expr: $.title
value_expr: $.key
search: { on_frontend: true }
target:
options_source:
connector: gorgias
method: proxy_list
args: { resource: ticket-fields }
label_expr: $.label
value_expr: $.name
search: { on_frontend: true }| Field | Type | Required | Description |
|---|---|---|---|
source / target |
object | Yes | An option source for each side of the mapping. |
default |
array | No | Seeds initial mapping rows; must be an array. |
allow_transform |
boolean | No | Enables the per-row JSONata transform editor. |
validation_expr |
string | No | JSONata run against the value before persisting. |
cardinality |
string | No | one_to_one (default, unique targets) or many_to_one (relaxes target uniqueness). |
extra_columns |
array | No | Typed per-row fields: { key (required), label?, type: text | select | boolean, options?, required? }. |
status_expr |
string | No | JSONata per row → { label, tone } status badge. |
row_action |
string | No | Action widget ID rendered per row; the row is merged into the action's JSONata context. |
Defaults and snapshots
- When a Job is created, each entry's defaults seed the Job's stored values: a
formentry contributes an object of its fields'defaultvalues; afield_mappingentry contributes itsdefaultarray. - Saving configuration affects future runs only. When a run starts, the current values are snapshotted onto
runs.job_config, so each run keeps an auditable copy of the configuration it used. - Tasks read the saved values in JSONata as
job_config.<key>(for examplejob_config.migration_step.stage).
API
GET /api/jobs/{id}/config— returns{ schema, config }(declared schema plus current values). Read this before writing.PUT /api/jobs/{id}/config/{key}— save one key: body{ value }, where aformvalue is an object and afield_mappingvalue is an array.PUT /api/jobs/{id}/config— replace the whole{ config }object.POST /api/jobs/{id}/config/{key}/options— resolve connector-backed picker options for a form field or afield_mappingside.
All three write/option endpoints require the admin or superadmin role; the GET is available to any authenticated user.
Values are validated against the Job's schema on save.
Related
- Job config: forms and field mapping — when and how to author job configuration
- Input and action widgets — dashboard widgets that edit the same keys
- Job template YAML — where the
job_configblock lives