Skip to content
TheThinkLoop

Template - Policy

Predicate

Refund eligibility

Whether a refund request should be approved under your written refund policy.

A predicate decision for refund requests, with evidence checks for the facts a policy usually turns on: duplicate charges, the refund window, and refund history.

The decision

PredicateA probability from 0 to 1 that the condition holds.

Should this refund request be approved under our 30-day refund policy?

Evidence checks (asked in the same request)

  • Duplicate charge: The customer reports being charged more than once.
  • Within refund window: The purchase was made within the 30-day refund window.
  • Prior refunds: The customer has received a previous refund.

Expected output: A probability from 0 to 1 that the request should be approved, plus one probability per evidence check.

Input

The Decisions API reads one input. Combine these fields into it as labeled text so the model sees the facts the decision depends on.

Input fields
FieldTypeRequiredDescription
messagestringYesThe customer's message, verbatim. Include the subject line if there is one.
purchase_datestringNoISO date of the purchase. Prepend it to the input so the model doesn't have to infer it.
prior_refund_countnumberNoRefunds this customer has already received.

Worked examples

  1. Duplicate charge, five days after purchase

    I was charged twice for my annual plan (order #48213). I only signed up once, 5 days ago. Please refund the duplicate charge.

    A careful reviewer would say: Yes. A duplicate charge is a billing error, and the request is inside the window.

    Run this example
  2. Change of mind, seven months later

    I bought the Pro plan 7 months ago and used it daily, but I no longer need it. Can I get my money back?

    A careful reviewer would say: No. Well outside the 30-day window, with heavy use and no fault on the company's side.

    Run this example

Expected answers are human judgments written for this template, not model output.

How it works

Refund decisions are a good first candidate for automation because the policy is usually written down and the outcome is binary. The predicate asks one thing: does this request meet the policy?

Put the policy's actual terms in the question. "Under our 30-day refund policy" gives the model a concrete test. "Should we refund this?" invites it to apply its own idea of fairness.

The evidence checks do two jobs. They show a reviewer why a request scored the way it did, and they give you facts you can gate on directly: you may choose to auto-approve every duplicate charge that billing data confirms, regardless of the overall probability.

Human review and thresholds

Recommended review policy

Automate approvals only at high probability and when the amount is under a limit you set. Send mid-range probabilities to a person. Consider routing every likely denial to review at first: a wrongly denied refund costs more goodwill than a slow one.

Choosing thresholds

The two errors are not symmetric. A false approval costs the refund amount. A false denial costs a customer relationship and possibly a chargeback. Most teams should set a higher bar for automated denials than for automated approvals, and scale the approval bar with the refund amount.

Starting automation threshold
90%
Starting don’t-decide threshold
60%

Starting points for the playground, not recommendations. The right values depend on your costs and on how the model’s confidence tracks accuracy on your data. Calibrate them.

Limitations

  • The model only sees what you send. If purchase dates and refund history live in your billing system, include them in the input rather than hoping the customer mentions them.
  • Customers can be wrong or dishonest about facts. A stated duplicate charge should be verified against billing data before money moves.
  • Policies with judgment clauses ("at our discretion", "in exceptional circumstances") need a separate decision. See the policy exception template.

Use it in your code

The template definition is plain JSON: the question, the evidence checks, the input fields, and the starting policy. The SDK call below sends the same question and checks to the Decisions API from your server.

refund-eligibility.jsonjson
{
  "$format": "thethinkloop.template/v1",
  "slug": "refund-eligibility",
  "title": "Refund eligibility",
  "decides": "Whether a refund request should be approved under your written refund policy.",
  "question": {
    "name": "decision",
    "type": "predicate",
    "instructions": "Should this refund request be approved under our 30-day refund policy?"
  },
  "evidenceChecks": [
    {
      "name": "factor_1",
      "label": "Duplicate charge",
      "type": "predicate",
      "instructions": "The customer reports being charged more than once."
    },
    {
      "name": "factor_2",
      "label": "Within refund window",
      "type": "predicate",
      "instructions": "The purchase was made within the 30-day refund window."
    },
    {
      "name": "factor_3",
      "label": "Prior refunds",
      "type": "predicate",
      "instructions": "The customer has received a previous refund."
    }
  ],
  "inputs": [
    {
      "name": "message",
      "type": "string",
      "required": true,
      "description": "The customer's message, verbatim. Include the subject line if there is one."
    },
    {
      "name": "purchase_date",
      "type": "string",
      "required": false,
      "description": "ISO date of the purchase. Prepend it to the input so the model doesn't have to infer it."
    },
    {
      "name": "prior_refund_count",
      "type": "number",
      "required": false,
      "description": "Refunds this customer has already received."
    }
  ],
  "expectedOutput": "A probability from 0 to 1 that the request should be approved, plus one probability per evidence check.",
  "examples": [
    {
      "title": "Duplicate charge, five days after purchase",
      "input": "I was charged twice for my annual plan (order #48213). I only signed up once, 5 days ago. Please refund the duplicate charge.",
      "expected": "Yes"
    },
    {
      "title": "Change of mind, seven months later",
      "input": "I bought the Pro plan 7 months ago and used it daily, but I no longer need it. Can I get my money back?",
      "expected": "No"
    }
  ],
  "startingPolicy": {
    "automateAt": 0.9,
    "abstainBelow": 0.6,
    "note": "A starting point for exploration, not a recommendation. Calibrate against your own labeled examples."
  }
}
Equivalent SDK calljavascript
import OpenAI from "openai"; // openai >= 7.30.0

const client = new OpenAI(); // reads OPENAI_API_KEY on the server

const decision = await client.decisions.create({
  model: "gpt-6-luna",
  input: "I was charged twice for my annual plan (order #48213). I only signed up once, 5 days ago. Please refund the duplicate charge.",
  questions: [
    {
      type: "predicate",
      name: "decision",
      instructions: "Should this refund request be approved under our 30-day refund policy?"
    },
    {
      type: "predicate",
      name: "factor_1",
      instructions: "The customer reports being charged more than once."
    },
    {
      type: "predicate",
      name: "factor_2",
      instructions: "The purchase was made within the 30-day refund window."
    },
    {
      type: "predicate",
      name: "factor_3",
      instructions: "The customer has received a previous refund."
    }
  ],
});

// Answers come back in question order. A question can also be refused.
const [main, ...checks] = decision.answers;
if (main.type === "refusal") throw new Error("The model declined to answer.");
if (main.type === "predicate") {
  console.log(main.probability); // 0–1 estimate that the condition is true
}

Download it as refund-eligibility.json, or browse all developer resources.

Need this decision tuned to your policy?

We are running a small number of pilots with B2B teams: your policy, your examples, your thresholds. Request early access.