Answer a few questions
Every build asks one round of questions about the JSON you sent, most useful first (at most about 25). Each is about a field, a question or a choice of your JSON, and nothing else. Every answer is optional; more help gives a better model.
| kind | asks |
|---|---|
examples | 10-50 real states across named situations: one for each answer of your decision, an ordinary moment, a rare one |
choice_boundary | how you tell two similar choices apart |
priorities | unwritten rules: which answer comes first when more than one fits |
choice_meaning · yes_meaning · score_ends | when an answer is right |
ready_signal | whether a yes/no field is a ready-made signal your program computes |
field_units | a field's unit and its lowest and highest real values |
field_meaning | what a field means |
Wait for the answers, or not
"interview": trueonPOST /v1/build: the build waits for your answers (statusawaiting_answers) up toanswer_timeout_seconds(default 600, at most 3600), then goes on with what it has. The MCP connector'sbuild_modeldoes this by default.- Without it: the questions are there while the build runs. Answers that arrive before it starts are used; later ones are saved for your next retrain.
Read them
{ "build_id": "bld_…", "round": 1, "status": "open", "answer_by": "2026-09-30T14:10:00Z",
"questions": [
{ "id": "q01", "kind": "examples", "priority": 1,
"text": "Send 10 real states your program sends, across these situations: one where `action` is `approve`; …",
"refs": { "question": "action", "choices": ["approve", "escalate", "decline"], "fields": [] },
"answer_with": { "examples": "a list of {\"situation\", \"state\", \"answers\"}" } },
{ "id": "q02", "kind": "choice_boundary", "priority": 2,
"text": "In `action`, how do you tell `approve` from `escalate`? What tips a case from one to the other?",
"refs": { "question": "action", "choices": ["approve", "escalate"], "fields": [] },
"answer_with": { "text": "a sentence or two (up to 600 characters)" } } ] }Answer them
{ "answers": [
{ "id": "q01", "examples": [
{ "situation": "a large refund", "state": { "order": { "amount": 820 }, "customer": { "tier": "free" } },
"answers": { "action": "escalate" } } ] },
{ "id": "q02", "text": "Escalate when a person should look: unusual amounts or an upset customer." },
{ "id": "q05", "unit": "dollars", "range": [0, 5000] },
{ "id": "q06", "ready_made": true, "text": "our fraud service sets it" },
{ "id": "q07", "skip": true } ],
"done": true }answersobject[]required- One per question: its
idand the keys itsanswer_withlists:text(up to 600 characters),unitandrange([lowest, highest]),ready_made(true or false),examples(up to 50 real states like the one you sent, each with a shortsituationand, if you know it, theanswersyou'd expect), orskip. doneboolean- Default
true: that's all, the build goes on now.false: more answers follow, and it keeps waiting up to its timeout. roundinteger- The round you answer (default: the latest).
The answer says what was recorded (accepted), what wasn't and why (rejected), and where your answers go (used: this_build or next_retrain). Your answers are read as information about your decision: they add notes on your fields, real examples your model's situations are made from, and what you said about your choices. They never change your hard rules.
A short follow-up, only when it helps
After the check, a build that asked its questions may ask a few more (at most 6), and only when it found a real gap: two choices it mixes up, or a question below the bar. It never holds your model up: answer them and retrain for a better version (POST /v1/domains/{domain}/train). The advice points them out.
In the console and the CLI
The build's page has a form for the questions. In the CLI:
canonopy build jev-request.json --interview # the build waits for your answers
canonopy build questions BUILD_ID
canonopy build answer BUILD_ID # asks each question on the terminal (Enter skips)
canonopy build answer BUILD_ID --file answers.json