Tasks
System One Model Call
Evaluates a state against one or more structured questions using a System One model. Returns typed judgments — choices, scores, and probabilities — that can be used directly in automation logic.
Unlike a general-purpose LLM call, System One models do not generate free-form text. Each question produces a structured, typed answer with a confidence score, making the results directly usable in task logic without parsing or prompting.
See Models for a full list of supported System One models.
Use cases
- Route an inbound message to the correct department based on its content.
- Score customer sentiment or urgency before deciding which workflow to trigger.
- Verify that a piece of text meets a condition before continuing a process.
- Pick the best match from a long list, such as a contact list, product catalogue, or knowledge base.
- Evaluate documents too long for a single model call.
Basic usage
Parameters
model required string
The System One model to use. Currently supported:
jev-latest: Always resolves to the latest stable Jev model.gpt-6-luna: OpenAI's GPT-6 Luna. Follows the org's preferred data residency and processing region.
See Models for a full list of supported models.
state required string | object | array
The content for the model to evaluate. All questions in the request see the same state.
State must contain text only. Images, audio, and video are not supported.
An object or array state is always sent exactly as given. Only a string state can be chunked (see data_processing.state.auto_chunk_large_text_states_into_multiple_calls).
questions required object
An object of named questions to evaluate against the state. Each key becomes the corresponding key in response.answers. All questions are evaluated independently in one request.
Each question has a type that determines its structure and the shape of its answer.
questions[name].type required string
The question type. One of noul, choice, or score.
questions[name].instructions required string
A natural language description of what the model should evaluate.
questions[name].criteria object | array | string
Defines the valid answer space for choice and score questions. Not used for noul questions.
For score: an array of strings describing each point on the scale, ordered from lowest to highest.
For choice: the options the model can pick from. A choice question accepts up to 255 options, or more with auto_split_on_max_choices. The options can be given in any of these formats:
An object is the most precise format: each key is a valid answer and each value describes it.
For arrays and separated strings, the key for each option is generated from its text:
- The text is lowercased, accents are removed, and anything other than letters and numbers becomes
_. For example,"Café Crème!"becomescafe_creme. - Keys that would clash get a number:
"Good Afternoon"and"good afternoon!"becomegood_afternoonandgood_afternoon_1. - Values that aren't text are converted to text first. Empty values are skipped.
- The original text becomes the option's description, and is returned in
choice_criteria_value.
A string is split on commas and line breaks, unless it's marked as CSV with criteria_is_csv.
data_processing object
Optional processing applied before and after the model call. Use it to chunk long state, split long option lists, and add convenience fields to answers.
data_processing is never sent to the model.
data_processing.state.auto_chunk_large_text_states_into_multiple_calls boolean
When true and the state is a string too long for one model call, the state is split into chunks and every chunk is evaluated against the same questions. The response then contains one set of answers per chunk (see response.chunks).
- The size limit takes the questions into account: the longer the questions, the less room is left for state.
- Text is split at paragraph breaks where possible, then line breaks, sentences, and finally words.
- Chunks don't overlap.
- A state that fits in one call is evaluated normally, and the response has its usual shape.
- If the questions alone leave too little room for any state, the task returns an error asking you to reduce the number or size of the questions.
Default: false.
data_processing.state.state_is_csv boolean
Marks a string state as CSV text. When the state has to be chunked, it's split between rows instead of at paragraph breaks, and the header row is repeated at the top of every chunk so each chunk can be understood on its own.
Each chunk is still sent as a single string. Has no effect unless auto_chunk_large_text_states_into_multiple_calls is true and the state is too long for one call.
Default: false.
data_processing.questions.choice.auto_split_on_max_choices boolean
When true, a choice question with more options than set_max_choices is split into several questions named after the original with a number appended: article becomes article_1, article_2, and so on.
- Options are shared out evenly: 300 options with a maximum of 255 become two questions of 150.
- Each split question keeps the original
instructions. - The response lists the split question names in
response.split_questions.
Each split question picks its best option from its own share of the options only, so its probabilities can't be compared directly with those of the other split questions. To get a single answer across all options, also set auto_final_round_on_split.
Default: false.
data_processing.questions.choice.set_max_choices integer
The most options a single choice question may have before it's split. Must be between 3 and 255.
Default: 255, or 20 for CSV criteria.
data_processing.questions.choice.auto_final_round_on_split boolean
When true, the best options from each split question are asked again together in a final round. The winner is returned under the original question name, with a final_round field added.
For example, with 300 options split into article_1 and article_2, the top 5 options of each are asked again as one 10-option question, and its answer is returned as article.
- If the combined options still exceed
set_max_choices, they're split and asked again until one question remains. - The split answers (
article_1,article_2, …) are still included in the response. - Each round is an extra model call, and its tokens are added to
usage.
Default: false.
data_processing.questions.choice.final_round_candidates_per_split integer
How many of the best options from each split question go through to the final round. A split question never contributes more than half its options, so each round at least halves the field.
Default: 5.
data_processing.questions.choice.return_top_n integer
Adds choices_top_n to every choice answer: the n most likely options, from most to least likely.
data_processing.questions.choice.criteria_is_csv boolean | array
Marks string criteria as CSV text instead of a comma or line separated list.
true: every choice question with string criteria is treated as CSV.- An array of question names, e.g.
["contact"]: only those questions are treated as CSV. Each named question must be a choice question with string criteria.
See CSV criteria for how the rows become options.
Default: false.
data_processing.questions.noul.return_noul_as_boolean_on_threshold number
Adds noul_boolean to every noul answer: true when noul is at or above this threshold, otherwise false. The noul probability itself is left unchanged. Must be between 0 and 1.
Raise the threshold when a false true is costly, and lower it when missing a true is costly.
CSV criteria
With criteria_is_csv, a choice question can take a spreadsheet-style list of options, such as a contact list or product catalogue, exported as CSV text.
How the text is read:
The first row is the header. It names the columns. An empty column name is replaced by its position (an empty second column becomes
column_2), and repeated names get a number (name,name_1).Every other row becomes one option, keyed
row_001,row_002, … in order. With more than 999 rows the numbers get wider (row_0001).Each option's description is the row, labelled by column. The example above becomes:
The separator is detected from the header row: comma, semicolon, or tab.
Standard CSV quoting is supported. A value in double quotes can contain the separator or line breaks, and
""inside quotes is a literal quote.Blank rows and empty cells are left out. A row with an empty
citysimply has nocityfield.CSV questions are split at 20 options by default, even without
auto_split_on_max_choices, because each row is a full record. Setset_max_choicesto change this, andauto_final_round_on_splitto get a single winner.
The model answers with a row key such as row_002. The full row is returned in choice_criteria_value, so you can use answers.contact.choice_criteria_value.name directly.
The CSV must have a header row and at least one data row, otherwise the task returns an error.
Result
Properties
response.model string
The resolved model version that processed the request.
response.answers object
An object keyed by each question name provided in questions. Each answer's shape depends on the question type.
When choice questions are split, the split answers (name_1, name_2, …) appear here too, and with a final round the combined answer appears under the original name.
response.answers[name].noul number
For noul questions. A float between 0 and 1 indicating the probability that the condition described in instructions is true.
response.answers[name].noul_boolean boolean
For noul questions, when return_noul_as_boolean_on_threshold is set. true when noul is at or above the threshold.
response.answers[name].choice string
For choice questions. The key from criteria that the model selected.
response.answers[name].choice_criteria_value string | object
For choice questions. The description of the selected option from criteria. For array and list criteria this is the original text ("Good Afternoon" rather than good_afternoon); for CSV criteria it's the full row object.
response.answers[name].choices_top_n array
For choice questions, when return_top_n is set. The most likely options, from most to least likely:
response.answers[name].final_round object
For the combined answer of a split choice question, when auto_final_round_on_split is set. Contains rounds, the number of model calls it took including the first, and candidate_count, the number of options in the last round.
response.answers[name].confidence number
For choice and score questions. A float between 0 and 1 indicating the model's confidence in its answer.
response.answers[name].probabilities object
For choice and score questions. The full probability distribution across all options.
response.answers[name].score number
For score questions. The position on the scale defined in criteria, from 0 to the highest level. It's a weighted average of the levels, so it can fall between them: 1.43 on a 0–2 scale leans between the second and third levels. Use score_level for a whole level.
response.answers[name].score_level integer
For score questions. The zero-based index of the most likely level.
response.answers[name].score_criteria_value string
For score questions. The label from criteria for score_level.
response.answers[name].legend object
For score questions. Maps each score index back to the label from criteria for easy reference.
response.values object
A flat summary of every answer, keyed by question name, for easy use in templates:
noul:noul_booleanwhen a threshold is set, otherwise thenoulprobability.choice: the selected key.score: thescore.
response.split_questions object
Present when choice questions were split. Maps each original question name to its split question names, e.g. {"article": ["article_1", "article_2"]}.
response.chunks array
Present when the state was chunked. response.chunked is true, and response.answers and response.values are replaced by one entry per chunk, in order:
state_rangeis the character range of the original state that the chunk covers. Withstate_is_csv, the range covers the chunk's rows; the header row sits at the start of the state.estimated_state_tokensis an estimate, because the model's exact token count isn't known in advance.usageon each chunk is that chunk's own usage.
response.usage object
Token usage for the request. Contains input_tokens and output_tokens. When the task makes more than one model call (chunks or final rounds), this is the total across all of them.
Examples
Routing and sentiment in one call
Evaluate urgency, department routing, and frustration level together in a single request.
Structured state
Pass related context as an object so the model can evaluate the full picture.
Yes/no answers as booleans
Get true or false directly instead of a probability. Read the result from response.values.is_urgent or response.answers.is_urgent.noul_boolean.
Simple option lists
Give choice options as an array or a comma separated string when they don't need descriptions. The keys are generated for you.
The answers use the generated keys, e.g. "choice": "technical_support", with the original text in choice_criteria_value.
Pick a contact from a CSV list
Match a message to the right person in a contact list. The list is split into questions of 20 rows, and the best 5 rows from each go through to a final round.
The chosen row is in response.answers.contact.choice_criteria_value, e.g. {"name": "Bob Jones", "department": "Sales", "city": "Durban, KZN"}, and the three closest matches are in choices_top_n.
Evaluate a long document
Check a document that may be too long for one call. Each chunk is evaluated separately, so you can see which parts of the document matched.
If the document is long enough to be chunked, check response.chunked and read each chunk's values. Otherwise, the answer is in response.values as usual.