Skip to content

Field object

Every key inside a field spec, one section per key: what it does, its type and default, and a runnable example. This is the lookup page for schema keys; for the field types see Schema object, and for the keys inside a rule's when see Condition object.

A field value can be a short string ("number", "bool", …) or an object:

{
  "merchant": {"type": "string", "instruction": "Store name, copied exactly"},
  "total":    {"type": "number", "integer": true, "instruction": "Final total"},
  "paid":     {"type": "bool", "instruction": "Was it paid?"},
  "items":    {"type": "list", "items": {"type": "string"}, "max_items": 10}
}

Quick index

Key Applies to In one line
type all The field kind.
instruction all What the field means.
description all Alias of instruction.
enum enum The allowed values.
values enum Alias of enum.
nullable all Allow null.
depends_on all Run after these fields.
free_form string Long text, no "only the value" suffix.
extract string Value must be a verbatim copy.
votes typed Decode several times, majority wins.
vote_instructions typed Your own wordings for votes.
on all Rules checked in code.
on_reject all Value when the request is rejected.
max_digits number Maximum characters of the number.
integer number Whole numbers only.
items list Spec of each item.
max_items list Maximum number of items.
expr compute The formula.
round compute Decimal places of the result.
http call The HTTP request.
args call Values for {placeholders}.
expose call What later fields may see.
on_error call What to do when the call fails.

type

Type: string · Default: inferred (an enum key implies enum)

The field kind. One of:

string, number, bool, enum, list, compute, call.

{"type": "number"}

Aliases ("boolean", "integer" / "int", "float", "str", "array") and JSON-Schema nullable types ({"type": ["number", "null"]}) are accepted. See Type aliases. If the object has an enum or values key and no type, the field is an enum.

instruction

Type: string · Default: ""

What the field means. This is the single most important key for accuracy: it becomes the question the model answers. Alias: description.

{"type": "number", "instruction": "Final total paid by the customer, in rupiah"}

Say what the value is, not how to find it

"Final total paid by the customer, in rupiah" beats "look for the total". Name the traps (subtotal vs total, PPN vs PB1 vs Tax) and define null explicitly. See Writing good instructions.

description

Type: string

Alias of instruction. Use whichever reads better; if both are present, instruction wins.

{"type": "string", "description": "Store name"}

enum

Type: array · Default: – (required for an enum field)

The allowed values. Up to 24 values; strings or numbers. Put null in the list to allow no answer.

{"enum": ["inpatient", "outpatient", "other", null], "instruction": "Claim type"}

The instruction automatically lists the allowed values, and the value is constrained while it is generated — the model can only produce one of them. A spec with enum (and no type) is an enum field.

values

Type: array

Alias of enum, for specs that use type elsewhere.

{"values": ["low", "medium", "high"]}

nullable

Type: boolean · Default: false

Allow the field to be null when the value is not present in the input.

{"type": "string", "instruction": "Tax number", "nullable": true}

The prompt then says "if this field is not present, answer with EXACTLY: null". For an enum field, prefer putting null in the enum list instead. A nullable number has no name = prefill (that would make 0 beat null), so the empty case is decided by probability mass. Equivalent JSON-Schema form: {"type": ["number", "null"]}.

depends_on

Type: array of field names · Default: []

Run this field in a later stage and show it the values of these fields. Execution order comes only from depends_on. Unknown names and cycles are rejected before any inference.

{
  "total":    {"type": "number", "instruction": "Line totals added up"},
  "tax_rate": {"type": "number", "instruction": "Tax percentage",
               "depends_on": ["total"]}
}

A field sees only its upstream values (its dependencies, direct and indirect); other fields that happened to finish are hidden, so a value cannot leak into an unrelated prompt. See Multi-step schemas.

free_form

Type: boolean · Default: false · string only

Long text: reasoning, summaries, replies. Removes the "Answer with ONLY the value" suffix so the model may write prose.

{"type": "string", "instruction": "Explain the decision in one paragraph",
 "free_form": true}

A free_form field has no confidence, and it cannot be combined with extract or votes, or with confidence_* rules — these raise HTTP 400.

extract

Type: boolean · Default: false · string only

The value must be a verbatim span of the input (context and messages). The model can only select text that already exists; it cannot invent or re-spell.

{"type": "string", "extract": true, "instruction": "Store name as printed"}
  • Formatting is kept as written (3201-4567 keeps its hyphen) — normalise it in your own code if needed.
  • Text only: not supported on images or on list items, and cannot be combined with free_form.

votes

Type: integer 1–5 · Default: 1

Decode the field several times with different instructions in the same batch, then take the majority. The confidence becomes the lower of the winning lanes' confidence and the agreement rate.

{"type": "number", "instruction": "Total paid", "votes": 3}

Not allowed on free_form (long prose rarely repeats exactly). See Confidence and review.

vote_instructions

Type: array of strings

Your own alternative wordings for votes. If set, votes defaults to 1 + len(vote_instructions) when not given.

{"type": "number", "instruction": "Total",
 "vote_instructions": ["total as digits only", "the grand total, no separators"]}

on

Type: array of rule objects · Default: []

Checks run in code right after the field's stage finishes. Rules may drop, reject, return, jump, switch, end or review.

{
  "insurance_no": {
    "type": "string", "nullable": true,
    "instruction": "Insurance number, digits only; null if absent.",
    "on": [{"when": {"len_lt": 16}, "do": "reject"}]
  },
  "reply": {
    "type": "string", "free_form": true,
    "depends_on": ["insurance_no"],
    "on_reject": "Insurance number rejected: it must have 16 digits."
  }
}

Within a field, rules are checked in array order; the first matching flow action is applied. See Rule object and Flow rules.

on_reject

Type: any · Default: null

The value this field gets when a reject rule stops the run before this field ran (or in the same stage as the rejecting field).

{"type": "string", "free_form": true, "on_reject": "Request cannot be processed."}

max_digits

Type: integer · Default: 8 · number only

Maximum characters of the number, counting - and .. 12345678 fits, 123456789 does not. Money fields often need 10–12.

{"type": "number", "integer": true, "max_digits": 12, "instruction": "Amount in rupiah"}

integer

Type: boolean · Default: false · number only

Whole numbers only; the value is returned as an integer (no decimal point).

{"type": "number", "integer": true}

Also set by "type": "integer" or "type": "int".

items

Type: field spec · Default: "string" · list only

The spec of each item: string, number, bool or enum. Not lists, objects, compute or call.

{"type": "list", "items": {"type": "number", "integer": true, "max_digits": 3},
 "instruction": "HTTP error codes in the log"}

Put on and depends_on on the list field, not on items. String items are free text split per line (bullets and 1. numbering removed); typed items are grammar-constrained.

max_items

Type: integer · Default: 20 · list only

Maximum number of items. After this many, only the end of the list is allowed.

{"type": "list", "items": {"type": "string"}, "max_items": 5}

expr

Type: string · compute only (required)

The formula, calculated by code (not the model). Field names, numbers, + - * /, parentheses, and abs, min, max, round.

{"type": "compute", "expr": "total_installment / net_salary * 100", "round": 2}

Referenced fields are added to depends_on automatically. A missing or non-numeric input, or division by zero, gives null. See Computed fields.

round

Type: integer 0–10 · compute only

0 gives an integer; 1–10 round to that many decimals; omitted keeps the full float.

{"type": "compute", "expr": "subtotal - discount + tax", "round": 0}

http

Type: object · call only (required)

The HTTP request. Sub-keys:

Sub-key Default Description
method GET GET, POST, PUT, PATCH, DELETE, HEAD.
url required Absolute http(s) URL; the host must be literal.
query {} Query parameters. {name} is filled from args.
headers {} Headers, e.g. {"Authorization": "Bearer {{secret.token}}"}.
body – JSON body (not for GET/HEAD).
timeout 10 Seconds (maximum 60).
response.select whole body Path (data.items[*].name) or {name: path}.
response.not_found [] Statuses meaning "no such thing" → null, not an error.
retry.attempts 0 0–3; GET/HEAD only unless retry.unsafe: true.
{"type": "call",
 "http": {"method": "GET", "url": "https://api.example.com/policy/{id}",
          "headers": {"Authorization": "Bearer {{secret.token}}"},
          "timeout": 10,
          "response": {"select": "data", "not_found": [404]}}}

See Tool calls for placeholders, secrets and security.

args

Type: object · call only

Values for the {name} placeholders in the URL, query, headers, body and response.select. "$field" or "$field.path" takes another field's value and adds it to depends_on; anything else is a constant.

{"args": {"id": "$policy_number", "currency": "idr"}}

expose

Type: array of keys, or true · call only · Default: nothing

What later prompts may see from the call result. A list of keys, true for the whole value, or omitted for nothing (safe default). The full value is always in result.

{"expose": ["name", "status"]}

on_error

Type: "null" | "review" | "reject" · Default: "null" · call only

What happens on a network error, timeout, unexpected status, oversized response or invalid select.

{"on_error": "reject",
 "on": [{"at": "status", "when": {"ne": "active"}, "do": "reject"}]}

reject is the safe choice for data an answer is built on (the on rules still run on the null value, so {"when": {"eq": null}, "do": "reject"} is a common companion). Use review for data that only supports the answer.