> ## 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.

# user_approval

> Prompt the user to approve or reject an action in the Narada browser UI

The `user_approval` method shows an approval card in the Narada browser UI and waits for the user to choose one of two buttons.

Use this when a Python agent should not continue until a person explicitly approves or rejects the next action.

<Note>
  For a higher-level guide covering both human-in-the-loop methods, see [Human-in-the-Loop Steps](/documentation/human-in-the-loop).
</Note>

## Method Signature

```python theme={null}
async def user_approval(
    self,
    *,
    step_id: str,
    prompt_message: str,
    approve_label: str,
    reject_label: str,
    timeout: int | None = 300,
) -> bool
```

## Parameters

<ParamField query="step_id" type="str" required>
  A stable identifier for this approval step.

  ```python theme={null}
  step_id="approve-invoice-submission"
  ```
</ParamField>

<ParamField query="prompt_message" type="str" required>
  The message shown in the approval card.

  ```python theme={null}
  prompt_message="Submit this invoice for approval?"
  ```
</ParamField>

<ParamField query="approve_label" type="str" required>
  The label for the button that returns `True`.

  ```python theme={null}
  approve_label="Submit"
  ```
</ParamField>

<ParamField query="reject_label" type="str" required>
  The label for the button that returns `False`.

  ```python theme={null}
  reject_label="Cancel"
  ```
</ParamField>

<ParamField query="timeout" type="int | None" default="300">
  Maximum time in seconds to wait for the user response. The default is 300 seconds, and the maximum is 3600 seconds.
</ParamField>

## Return Value

<ResponseField name="approved" type="bool">
  `True` when the user clicks the approve button. `False` when the user clicks the reject button.
</ResponseField>

If the interaction is cancelled or aborted, the method raises `UserAbortedError`.

## Example

```python theme={null}
import asyncio

from narada import Agent, BrowserEnvironment, UserAbortedError

async def main():
    env = BrowserEnvironment()
    agent = Agent(environment=env)

    try:
        try:
            approved = await agent.user_approval(
                step_id="approve-send-message",
                prompt_message="Send the drafted message to the customer?",
                approve_label="Send",
                reject_label="Do not send",
                timeout=300,
            )
        except UserAbortedError:
            print("The approval step was cancelled.")
            return

        if not approved:
            print("The user rejected the action.")
            return

        await agent.run(prompt="Send the drafted message.")
    finally:
        await env.close()

if __name__ == "__main__":
    asyncio.run(main())
```
