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

# Approvals

> Approve or deny a payment held for review

When a payment breaches a limit whose action is **hold**, Natural does not reject it. Natural holds the payment and opens an approval process. The call that sent the payment still returns `2xx`, and no money moves until someone approves.

## List what is held

[`GET /approvals`](/api-reference/approvals/list-approvals) lists what is held, showing pending holds by default.

<CodeGroup>
  ```python Python theme={null}
  approvals = client.approvals.list(status="pending")
  ```

  ```typescript TypeScript theme={null}
  const approvals = await client.approvals.list({ status: "pending" });
  ```

  ```bash CLI theme={null}
  natural approvals list --status pending --limit 50
  ```

  ```bash cURL theme={null}
  curl "https://api.natural.com/approvals?status=pending&limit=50" \
    -H "Authorization: Bearer $NATURAL_API_KEY"
  ```
</CodeGroup>

Each record names the payment it holds and every reason it was held:

<Snippet file="api-examples/approvals.list.response.mdx" />

## Approve or deny

[`POST /approvals/{approvalId}/approve`](/api-reference/approvals/approve-payment-or-transfer) releases the original payment. [`POST /approvals/{approvalId}/deny`](/api-reference/approvals/deny-payment-or-transfer) cancels it.

<CodeGroup>
  ```python Python theme={null}
  import uuid

  client.approvals.approve("apr_550e8400e29b41d4a716446655440000", idempotency_key=str(uuid.uuid4()))
  # or
  client.approvals.deny("apr_550e8400e29b41d4a716446655440000", idempotency_key=str(uuid.uuid4()))
  ```

  ```typescript TypeScript theme={null}
  await client.approvals.approve({
    approvalId: "apr_550e8400e29b41d4a716446655440000",
    idempotencyKey: crypto.randomUUID(),
  });
  // or
  await client.approvals.deny({
    approvalId: "apr_550e8400e29b41d4a716446655440000",
    idempotencyKey: crypto.randomUUID(),
  });
  ```

  ```bash CLI theme={null}
  natural approvals approve --approval-id apr_550e8400e29b41d4a716446655440000 --idempotency-key "$(uuidgen)"
  # or
  natural approvals deny --approval-id apr_550e8400e29b41d4a716446655440000 --idempotency-key "$(uuidgen)"
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.natural.com/approvals/apr_550e8400e29b41d4a716446655440000/approve \
    -H "Authorization: Bearer $NATURAL_API_KEY" \
    -H "Idempotency-Key: $(uuidgen)"
  ```
</CodeGroup>

The record comes back resolved, with `status` now `approved` and `resolvedAt` set:

<Snippet file="api-examples/approvals.approve.response.mdx" />

Approving clears only the gate you own. If the payment also breached a gate owned by someone else, it stays held until that owner acts too. When several breached gates share one owner, they merge into one hold that lists every reason, and the highest breached limit is the one you are clearing.

<Snippet file="shared/webhook-approval.mdx" />
