> ## Documentation Index
> Fetch the complete documentation index at: https://docs.narada.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Human-in-the-Loop Steps

> Ask a user for approval or workflow variable values from a Narada Python agent

Human-in-the-loop steps let a Python agent pause at a controlled point, show a small card in the Narada browser UI, and continue after a person responds. Use them when an automation needs an explicit approval decision or values that should come from a human during the run.

<CardGroup cols={2}>
  <Card title="User Approval" icon="check">
    Ask the user to approve or reject before the workflow continues. The step returns `True` for the approve button and `False` for the reject button.
  </Card>

  <Card title="Prompt for User Input" icon="keyboard">
    Ask the user to fill one or more workflow variables. The step returns a dictionary keyed by variable name.
  </Card>
</CardGroup>

## When to Use These Steps

Use `user_approval` for checkpoints where the automation already has enough context, but should not continue without explicit consent. Examples include sending an email, submitting a form, approving a purchase, or making a destructive update.

Use `prompt_for_user_input` when the automation needs structured values before it can continue. Examples include asking for a date range, choosing an enum option, collecting a number, or asking for a small table of rows.

<Warning>
  These steps require a Narada browser context that can show the human interaction UI.
</Warning>

## User Approval

Call `agent.user_approval()` when the workflow needs a yes/no decision before continuing. You provide the prompt text and the labels for the approve and reject buttons.

The reject button is a normal response and returns `False`. A cancellation or aborted interaction raises `UserAbortedError`, so handle that separately from an explicit rejection.

See the [`user_approval` API reference](/api-reference/user-approval) for the full signature and example.

## Prompt for User Input

Call `agent.prompt_for_user_input()` when the workflow needs structured values from the user. You provide a list of variable definitions, and the method returns a dictionary containing the values the user submitted.

Supported variable types are `string`, `number`, `boolean`, `enum`, `dataTable`, `object`, and `array`. Optional variables may be omitted from the returned dictionary if the user leaves them blank.

For `dataTable` values, Narada serializes the table as:

```json theme={null}
{
  "columnNames": ["Name", "Email"],
  "rows": [
    ["Ada Lovelace", "ada@example.com"],
    ["Grace Hopper", "grace@example.com"]
  ]
}
```

See the [`prompt_for_user_input` API reference](/api-reference/prompt-for-user-input) for the full signature, variable schema, and example.

## Best Practices

<Steps>
  <Step title="Use stable step IDs">
    Set `step_id` to a stable, descriptive value. This makes traces and debugging easier when the same agent has multiple human interaction steps.
  </Step>

  <Step title="Keep approval prompts specific">
    Approval text should describe the exact action that will happen next. Avoid vague prompts like "Continue?" when the next step sends data, submits a form, or changes an external system.
  </Step>

  <Step title="Mark required inputs carefully">
    Use `required=True` only when the workflow cannot continue without the value. Optional values can be omitted from the returned dictionary.
  </Step>

  <Step title="Handle cancellation separately">
    Treat cancellation as control flow. Catch `UserAbortedError` and exit or branch cleanly instead of reporting it as an unexpected failure.
  </Step>
</Steps>

## API Reference

* [`user_approval`](/api-reference/user-approval)
* [`prompt_for_user_input`](/api-reference/prompt-for-user-input)
