# Deciding approval requests

> Find the approval requests waiting on you, check whether you may approve or reject each one now and what your approval would do, then decide.

> **Note — For assistants**
>
> An assistant connected to the Qualy MCP server reads this guide as the resource `qualy://guides/approvals`. Generated from the Qualy MCP server’s guide registry.

Your account's approval policies hold some charges, payouts, payment splits, direct-debit agreements, refunds and export deliveries until approvers decide, and approving can release money. Do it in this order: find what is waiting, check what you may do, then decide.

## 1. Find what is waiting

Call `approval_request_list` with `status` pending. You see what the dashboard shows you: every request, your team's, or only those you created, are assigned or have acted on. Narrow it with `entityType` (and `entityId` for one record). Each row carries `viewer`, so you can tell which ones you may decide now.

A record shows its own approval too:

- `payout_get` returns `approval`: who approves, in order, under which strategy, who already decided, and `viewer`.
- `payment_split_get` returns the split's own `approval` and, when a direct-debit charge on it is held for an approver, `chargeApproval`. A split's approval is decided when its payout is prepared, so a new split has none yet; an automatic split's release is approved on its payout.
- A refund names its approval request; [`qualy://guides/refunds`](/docs/mcp-server/guides/refunds.md) covers deciding refunds.

## 2. Check what you may do

`approval_request_get` returns the request with its policy, approvers, assignment and decisions, and `viewer`: the same check approving and rejecting run.

- `canApprove`: it is pending, you are a listed approver, it is your turn (Sequential) or you are assigned (Round-robin), you are active and still hold an approver role, and you haven't decided yet.
- `canReject`: it is pending, you are a listed approver (any of them, at any time), and you haven't decided yet.
- `approveRefusal` and `rejectRefusal`: when you may not, the code and message the action would return.
- `progress`: what your approval would do, `approved` of `required`, and `wouldResolve` when yours is the one that passes it.

The strategy decides when a request passes:

- **Any approver** and **Round-robin** (the `assignedApprover`): one approval passes it.
- **All approvers**: every listed approver must approve.
- **Sequential**: every listed approver, one after another, in order.
- Any listed approver may reject at any time, even out of turn, and one rejection stops it.

## 3. Decide

`approval_request_approve` and `approval_request_reject` take the `requestId` and an optional `comment` recorded on the request. Their previews refuse up front what deciding would refuse, and say in the dashboard's words what approving does:

- A payout sends the amount to its recipient. In another currency, what you approve is what the recipient receives; what you send is a live quote, re-priced when the money moves.
- A payment split sends the amount to its recipient as their split.
- A refund refunds the customer and sends the money. It can't be undone.
- A charge charges the customer. An external payment is only recorded, and an offset moves no money.
- A direct-debit agreement moves no money: its amount is the most that could ever be debited over the agreement's whole period. Rejecting it cancels the agreement, which leaves that payment unable to go out.
- An export delivery delivers the export file to its destination. Rejecting it cancels that delivery, and nothing is delivered.

Under All approvers or Sequential, the preview says when your approval is not the last one needed. The result is the request: `status` approved means it passed and what it held goes ahead; still pending means your approval is recorded and the rest are needed. Rejecting stops what it held.

## When a decision no longer counts

A record's `approval` reads `superseded` when the decision no longer covers it: when it was released, its amount or currency had changed, or, for a cross-currency payout, the amount funding it had risen more than the policy's FX drift tolerance (5% by default), so the release was refused. Its status stays as it was, and the next attempt to release it raises a new request. When a newer request replaces one, the record shows the newer request; the old one (`approval_request_list` with `entityId`) has `supersededReason` and `supersededBy`, the request that replaced it.

## Worked examples

### See what is waiting

```json
{
  "tool": "approval_request_list",
  "arguments": {
    "status": "pending"
  }
}
```

Per row, viewer.canApprove and viewer.canReject say what you may do now. Use count and hasMore for totals.

### Check one request before deciding

```json
{
  "tool": "approval_request_get",
  "arguments": {
    "requestId": "66f1d0a3e4b0a1b2c3d4e5f8"
  }
}
```

If viewer.canApprove is false, approveRefusal says why. progress says whether your approval would pass it.

### Approve it

```json
{
  "tool": "approval_request_approve",
  "arguments": {
    "requestId": "66f1d0a3e4b0a1b2c3d4e5f8",
    "comment": "Matches the signed agreement."
  }
}
```

Read status in the result: approved means it passed; pending means others still need to approve.

Previews first: the call returns a preview to show the person. Call it again with the same arguments plus `confirmationId` and `userConfirmed: true` only after they approve.

### Reject it

```json
{
  "tool": "approval_request_reject",
  "arguments": {
    "requestId": "66f1d0a3e4b0a1b2c3d4e5f8",
    "comment": "The amount does not match the invoice."
  }
}
```

Previews first: the call returns a preview to show the person. Call it again with the same arguments plus `confirmationId` and `userConfirmed: true` only after they approve.
