Template - Revenue
PredicateLead qualification
Whether an inbound lead is worth a salesperson's time.
A predicate decision for inbound inquiries, with evidence checks for authority, fit, and timing.
The decision
Is this inbound lead worth a sales call?
Evidence checks (asked in the same request)
- Decision-maker: The sender holds a senior title or budget authority.
- Team size fits: The company or team size is 20 people or more.
- Buying timeline: The sender states a timeline or an active evaluation.
Expected output: A probability from 0 to 1 that the lead is worth a call, 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.
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | The customer's message, verbatim. Include the subject line if there is one. |
enrichment | string | No | Firmographic data you already hold: company size, industry, existing customer or not. |
Worked examples
Senior buyer with budget and a timeline
Hi, I'm Head of Support at a 240-person B2B SaaS company. We have 45 agents on Zendesk and budget approved to automate triage this quarter. Can we get a demo and pricing?
A careful reviewer would say: Yes. Authority, a sizeable team, an approved budget, and a stated timeline.
Run this exampleStudent project
I'm a student writing a thesis on AI classification. Is there a free forever plan I could use for a personal project?
A careful reviewer would say: No. No commercial intent. Better served by documentation and a free tier.
Run this example
Expected answers are human judgments written for this template, not model output.
How it works
"Worth a sales call" means something different at every company. Replace the evidence checks with your own qualification criteria. The three here are a common starting set, not a recommendation.
The checks matter more than the headline number. A lead that passes on fit and authority but has no timeline may belong in nurture rather than in a rep's calendar.
Human review and thresholds
Recommended review policy
Automate the confident ends: book a call for strong leads and send self-serve resources to clear non-fits. Have a person review the middle. Check a sample of automated rejections every week, because lost revenue is invisible unless you look for it.
Choosing thresholds
A wrongly rejected lead costs a deal you never hear about. A wrongly accepted one costs a rep thirty minutes. When pipeline is thin, lower the bar for a call. When reps are overloaded, raise it.
- Starting automation threshold
- 85%
- Starting don’t-decide threshold
- 55%
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
- Short form submissions contain little evidence. Enrich the input with firmographic data before deciding.
- Signals like job title are easy to misstate, and good leads sometimes write one line.
- The template scores the inquiry, not the opportunity. It knows nothing about your pipeline or territory rules.
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.
{
"$format": "thethinkloop.template/v1",
"slug": "lead-qualification",
"title": "Lead qualification",
"decides": "Whether an inbound lead is worth a salesperson's time.",
"question": {
"name": "decision",
"type": "predicate",
"instructions": "Is this inbound lead worth a sales call?"
},
"evidenceChecks": [
{
"name": "factor_1",
"label": "Decision-maker",
"type": "predicate",
"instructions": "The sender holds a senior title or budget authority."
},
{
"name": "factor_2",
"label": "Team size fits",
"type": "predicate",
"instructions": "The company or team size is 20 people or more."
},
{
"name": "factor_3",
"label": "Buying timeline",
"type": "predicate",
"instructions": "The sender states a timeline or an active evaluation."
}
],
"inputs": [
{
"name": "message",
"type": "string",
"required": true,
"description": "The customer's message, verbatim. Include the subject line if there is one."
},
{
"name": "enrichment",
"type": "string",
"required": false,
"description": "Firmographic data you already hold: company size, industry, existing customer or not."
}
],
"expectedOutput": "A probability from 0 to 1 that the lead is worth a call, plus one probability per evidence check.",
"examples": [
{
"title": "Senior buyer with budget and a timeline",
"input": "Hi, I'm Head of Support at a 240-person B2B SaaS company. We have 45 agents on Zendesk and budget approved to automate triage this quarter. Can we get a demo and pricing?",
"expected": "Yes"
},
{
"title": "Student project",
"input": "I'm a student writing a thesis on AI classification. Is there a free forever plan I could use for a personal project?",
"expected": "No"
}
],
"startingPolicy": {
"automateAt": 0.85,
"abstainBelow": 0.55,
"note": "A starting point for exploration, not a recommendation. Calibrate against your own labeled examples."
}
}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: "Hi, I'm Head of Support at a 240-person B2B SaaS company. We have 45 agents on Zendesk and budget approved to automate triage this quarter. Can we get a demo and pricing?",
questions: [
{
type: "predicate",
name: "decision",
instructions: "Is this inbound lead worth a sales call?"
},
{
type: "predicate",
name: "factor_1",
instructions: "The sender holds a senior title or budget authority."
},
{
type: "predicate",
name: "factor_2",
instructions: "The company or team size is 20 people or more."
},
{
type: "predicate",
name: "factor_3",
instructions: "The sender states a timeline or an active evaluation."
}
],
});
// 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 lead-qualification.json, or browse all developer resources.
Need this decision tuned to your policy?
Related
- Choice template
Sales routing
Which sales motion an inbound inquiry belongs to.
- Predicate template
Spam detection
Whether an inbound message is spam rather than a real customer contact.
- Choice template
Customer message routing
Which team should own a customer message: sales, customer success, support, or billing.
- Guide
Confidence thresholds
Probability, confidence, accuracy, calibration, and correctness are different things. How to set a review policy from the cost of each kind of mistake.
- Guide
Evaluating AI decisions
Accuracy alone hides the mistakes that matter. How to build a test set, which numbers to report, how to read failures, and when an evaluation is good enough to act on.
- Guide
Human-in-the-loop AI
When should AI decide and when should it ask? Review patterns, what reviewers need to see, sizing the queue, and keeping oversight real.