# Auto-approve refunds safely

Source: https://docs.temprl.org/examples/refund-gate

> Approve refund requests automatically when Simo is confident they meet the policy, and send borderline ones to a person.

Approve refunds automatically only when the request clearly meets the policy, decline the clear no's, and send everything in between to a person. Because the probabilities are calibrated, the thresholds translate directly into an error rate.

**Python**

```python
from simoai import Client, Fill, Noul

c = Client()

POLICY = """Refunds are allowed within 30 days of delivery for items that arrived damaged or not as described.
Opened software and gift cards are not refundable. Refunds over $500 need a manager."""

def decide(ticket: str, order: dict) -> str:
    r = c.ask(
        {"policy": POLICY, "order": order, "ticket": ticket},
        {
            "eligible": Noul("The refund request meets the policy"),
            "amount":   Fill("the amount the customer wants refunded, in dollars", kind="number"),
            "fraud":    Noul("The request shows signs of fraud or abuse"),
        },
        two_pass=True,   # read the amount first, then decide with it in view
    )
    p, amount = r["eligible"].noul, r["amount"].parsed
    if r["fraud"].noul > 0.3:
        return "review: possible abuse"
    if amount is not None and amount > 500:
        return "review: needs a manager"
    if p > 0.97:
        return f"approve ${amount}"
    if p < 0.05:
        return "decline"
    return f"review: eligible p={p:.2f}"

print(decide("The blender arrived with a cracked jug. I'd like my money back.",
             {"item": "Blender", "price": 89, "delivered": "2026-10-09", "today": "2026-10-18"}))
# approve $89.0
```

**JavaScript**

```javascript
const POLICY = `Refunds are allowed within 30 days of delivery for items that arrived damaged or not as described.
Opened software and gift cards are not refundable. Refunds over $500 need a manager.`;

async function decide(ticket, order) {
  const res = await fetch("https://api.temprl.org/v1/ask", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.SIMO_API_KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify({
      model: "simo-1-pro",
      state: { policy: POLICY, order, ticket },
      questions: {
        eligible: { type: "noul", instructions: "The refund request meets the policy" },
        amount: { type: "fill", instructions: "the amount the customer wants refunded, in dollars", kind: "number", max_tokens: 16 },
        fraud: { type: "noul", instructions: "The request shows signs of fraud or abuse" },
      },
      options: { two_pass: 1 },
    }),
  });
  const { answers: a } = await res.json();
  if (a.fraud.noul > 0.3) return "review: possible abuse";
  if (a.amount.parsed > 500) return "review: needs a manager";
  if (a.eligible.noul > 0.97) return `approve $${a.amount.parsed}`;
  if (a.eligible.noul < 0.05) return "decline";
  return `review: eligible p=${a.eligible.noul.toFixed(2)}`;
}
```

## Choosing the thresholds

Set each threshold from what a mistake costs, and let the calibration tell you the trade-off:

| Threshold to approve | Wrong approvals among those approved near the threshold | Share sent to people |
|---|---|---|
| 0.90 | about 1 in 10 | lower |
| 0.97 | about 3 in 100 | medium |
| 0.99 | about 1 in 100 | higher |

Log every decision with its probability, then check a sample: approvals made at 0.97 should be right about 97% of the time. The business rules (manager over $500, the fraud flag) stay in your code, where they are exact.
