What we’re building
We will build a refund workflow. A refund of 50 or less is approved by a rule. A larger one stops and asks a person. The run waits, as long as we allow, and then continues down the branch the answer picks. A step likeask raises an input request: a typed question with a prompt, the answers on offer, and a risk. The risk decides who may answer. Risk HIGH can only be answered by a person, never by a supervisor or an AI agent. Money is a good reason for that.
Save the workflow
Create The You should see:With an API key on the server, add
refund.json:refund.json
ask node waits for up to ttlSeconds (600, ten minutes). onTimeout: FAIL fails the step if nobody answers in time, so a refund is never paid by silence. After an answer, the message carries the decision in its metadata as input.decision, and verdict branches on it. Send it to the server:-H "X-API-Key: <your key>" to every call in this tutorial.Stuck?ASK_INPUTas an unknown type means the server is older than this feature or was built without it.curl http://localhost:9858/api/plugins/ASK_INPUTanswers404in that case.
Send a small refund: a rule decides
executionId from the answer and read the result:Send a big refund: the run waits
EXEC to the new executionId, and read the run:RUNNING, with ask running and everything after it pending:Stuck? IfaskisSKIPPEDand the run already finished, the amount was 50 or less and the rule took it. Use an amount above 50.
Find the question
The question is now open. List the open questions of the session:You should see the request (shortened). Note Keep its id:In the web UI the same question shows in the Inputs panel of the workflow page, with a button for each option.
risk and options:Answer it
We approve, and give a reason. The reason is recorded in the execution log:You should see the request The run goes on at once. Read its result as in step 2:
ANSWERED, with who answered (shortened):Stuck?409means the request is no longer open: someone answered it, or it expired. The message names the answer that won.403names the rule that failed (audience,tier,risk,scopeorseparation). Answering needs anOPERATORkey, and a request of riskHIGHis refused to a supervisor whatever its settings.
Say no
Start another big refund the same way, with another order, and find its question:Set You should see the run finish A rejection is only a decision here, so
EXEC and REQ for it as in step 4, then reject:SUCCESS with the other branch taken:verdict sends it to declined and the run records the outcome. Answering the same question again is refused:Answer from the command line, or from an assistant
Answer from the command line, or from an assistant
With the command-line client:An assistant uses the MCP tools
list_pending_inputs and answer_input. The yukta-workflows skill tells it to show you what waits and let you choose: approving is your decision, not the assistant’s.Without an API key every caller counts as a person, so this tutorial worked with no header. Once the server has keys, answering needs an
OPERATOR key, and the answer is recorded under that key’s name.What you just did
We made a workflow that handles the routine cases by rule and stops at the one that needs a person. Theask step turned into a typed question that we listed, read and answered over REST, and the run carried on with our answer. Whoever answers is checked against the request’s risk, so a high-risk question cannot be answered by anything but a person.
Where to go next
Who decides
Risk tiers, routes and why HIGH is a human decision.
Ask for input from a workflow
ASK_INPUT, the ask_for_input tool for agents, and WAIT_FOR_SIGNAL.
Route input requests
Send questions to a supervisor first, then to a person.
Add a supervisor
Let a rule answer or advise on the low-risk questions.