# Approvals

> Pause a workflow until someone approves or rejects it, or until someone replies.

Built-in step · 1 step. Web page: https://docs.lodol.com/docs/integrations/built-in/review

To learn when to use these steps, with examples, read [Ask for approval](https://docs.lodol.com/docs/guides/approvals.md).

## Steps

### Request approval

Pause the run until someone approves or rejects it (the default) or, set to ask for a written reply, answers a question that needs human input, like a PO number, a correction or which option to take. People get an email and an in-app notification with a link, and anyone outside the workspace can answer from the link without an account. The run waits without using any resources, then continues with the answer: add an If step on approved to act on a decision, or use reply. Chain several for multi-level approval, or put them in If branches to route by amount.

**Inputs**

- What to ask (`title`, text, required): One line people see first. For an approval, what needs approving, for example: Pay @bill.vendor $@bill.total for invoice @bill.number. For a written reply, the question, for example: Which PO number should the @bill.vendor invoice go against?
- What you need back (`response`, text): An approval, where people approve or reject (the default), or a written reply, which the next steps read as reply. One of: `approval` (Approve or reject), `reply` (A written reply). Default: `approval`.
- Details (`details`, text): Everything people need to answer: amounts, line items, what you need and in what form, and links to the source documents. Links are clickable in the email and the app.
- Who to ask (`approvers`, text): Email addresses of the people to ask, separated by commas. People in this workspace answer in the app; anyone else gets a secure link by email, so a client can answer without an account. Leave empty to let anyone in the workspace who can run workflows answer.
- Who can answer (`approver_group`, text): Only the people asked, the people asked plus the workspace's owner and admins, or anyone in the workspace who can run workflows (not Viewers). One of: `listed` (Only the people asked), `admins` (People asked, plus admins), `anyone` (Anyone who can run workflows).
- Time limit (hours) (`time_limit_hours`, number): How long to wait for an answer. Leave empty for 72 hours; at most 720 (30 days). Hours can be fractions, for example 0.5 for half an hour. From 0 to 720.0.
- If nobody answers in time (`on_timeout`, text): What happens when the time limit runs out. Left unset, an approval is rejected and a written reply stops the run with an error. Continuing without a reply gives the next steps an empty reply with timed_out set. One of: `reject` (Treat it as rejected), `approve` (Treat it as approved), `fail` (Stop with an error), `continue` (Continue without a reply).
- Remind every (hours) (`remind_every_hours`, number): Remind the people asked this often while the request waits (at most 10 reminders). Leave empty for no reminders. Hours can be fractions, for example 0.5 for half an hour. From 0 to 720.0.
- Escalate after (hours) (`escalate_after_hours`, number): If nobody has answered after this long, also ask the people in Escalate to. Must be shorter than the time limit. Hours can be fractions, for example 0.5 for half an hour. From 0 to 720.0.
- Escalate to (`escalate_to`, text): Email addresses to escalate to, separated by commas. Leave empty to escalate to the workspace's owner and admins.
- Require a different approver (`require_different_approver`, true/false): The person the run runs as can't approve it: whoever started it, or the workflow's owner for scheduled and triggered runs. Approvals only. Only when What you need back is Approve or reject. Default: `false`.
- Prepared by (`prepared_by`, text): Email addresses of whoever prepared this item, for example the person who entered the bill. They can't approve it. Approvals only. Only when What you need back is Approve or reject.
- Also post to Slack channel (`slack_channel`, text): A channel ID or #name to post the request to, with a link to answer. Uses this workspace's Slack connection; the Lodol app must be in the channel.

**Outputs**: The answer: the decision or the written reply, who gave it and when, and any comment left with a decision.

- `approval_id` (text)
- `approved` (true/false): True when the request was approved. Always false for a written reply.
- `comment` (text): What the approver wrote with their decision, if anything.
- `decided_at` (text): When they answered (ISO 8601).
- `decided_by` (object): Who answered.
- `decision` (text): approved or rejected, or replied for a written reply.
- `reply` (text): The written reply. Empty for an approval, and when nobody replied in time and the step was set to continue.
- `timed_out` (true/false): True when nobody answered in time and the time-limit outcome was applied.

**Example output**

```json
{
  "approval_id": "sample-approval",
  "approved": true,
  "comment": "Looks good.",
  "decided_at": "2026-01-15T16:30:00+00:00",
  "decided_by": {
    "email": "jordan@example.com",
    "name": "Jordan Lee"
  },
  "decision": "approved",
  "reply": "",
  "timed_out": false
}
```
