---
name: cold-reply-classifier
description: Classifies replies to cold email into labels (interested, meeting request, referral, not now, not interested, unsubscribe, hostile, out-of-office, auto-reply, bounce), extracts dates and referred contacts, recommends the next action for each, and counts human and automatic replies separately. Outputs JSON per reply and a summary with opportunities per 1,000 leads instead of reply rate. Use when the user pastes replies or an inbox export, asks to sort, tag or triage cold email replies, or wants to know how many real opportunities a campaign produced.
---

# Cold reply classifier

You sort replies to cold email into a fixed set of labels, pull out what the next action needs, and report results in a way that reflects pipeline, not reply volume.

## Step 1. Input

Accept pasted replies, a CSV or JSON export. For each reply you need at least: sender address, timestamp, campaign or sequence name, subject, reply text. The original email helps but is optional.

**Deduplicate first** by sender + timestamp + campaign. Exports often repeat the same message.

## Step 2. Labels

Assign exactly one label per reply:

| Label | Kind | Signs | Next action |
|---|---|---|---|
| `interested` | human | asks a question about the offer, "tell me more", "how does it work" | answer within the hour, propose a call |
| `meeting_request` | human | proposes or accepts a time, asks for a calendar | book it, send the invite |
| `referral` | human | points to another person, often with a name or address | write to that person, mention who referred you |
| `not_now` | human | "not this quarter", "check back in March" | stop sequence, schedule a follow-up on the date |
| `not_interested` | human | a clear no without hostility | stop sequence, no reply needed |
| `unsubscribe` | human | "remove me", "stop emailing" | add to suppression list at once, confirm only if asked |
| `hostile` | human | anger, threat to report, legal wording | suppress, no reply, flag for review |
| `out_of_office` | automatic | OOO, holiday, parental leave, return date | pause, resume after the return date if the tool allows |
| `auto_reply` | automatic | ticket created, "we received your message", generic autoresponder | stop sequence, not a human reply |
| `bounce` | automatic | delivery failure, mailbox not found, NDR | suppress address, count in bounce rate |

`interested`, `meeting_request` and `referral` with a named person are **opportunities**.

Rules for edge cases:

- A reply with a question and "not now" is `not_now`.
- A referral that only says "wrong person" with no name is `not_interested`, with `wrong_person: true`.
- Sarcasm or "who gave you my email" is `hostile` if it mentions reporting, otherwise `not_interested`.
- When unsure between two labels, pick the one with the more conservative action and set `confidence` below 0.7.

## Step 3. Extract fields

For every reply output one JSON object:

```json
{
  "sender": "jane@northwind.example",
  "timestamp": "2026-03-04T10:12:00Z",
  "campaign": "it-support-q1",
  "label": "not_now",
  "kind": "human",
  "opportunity": false,
  "confidence": 0.9,
  "follow_up_date": "2026-06-01",
  "referred_contact": null,
  "wrong_person": false,
  "next_action": "Stop sequence. Follow up on 2026-06-01.",
  "quote": "Reach out again in June."
}
```

`quote` is copied verbatim from the reply, never paraphrased.

## Step 4. Summary

Report per campaign:

- Human replies and automatic replies as two separate counts (not one "reply rate").
- Counts per label.
- Opportunities, and **opportunities per 1,000 leads contacted**. This is the number to compare campaigns on. Reply rate rises with "not interested" and "remove me" replies and says little about pipeline.
- Unsubscribes and hostile replies per 1,000 leads, as the complaint-risk signal.

## Rules

- Never invent a reply, a name or a date. If a field is not in the text, set it to null.
- Do not reply to anyone on the user's behalf unless asked.
- Treat auto-replies as information about delivery (the email arrived), not as interest.

## Example

Input: "Thanks, not a priority right now. Try me again after the summer. - Jane"

Output: `label: not_now`, `kind: human`, `opportunity: false`, `follow_up_date: 2026-09-01` (assumed from "after the summer"; confidence 0.75), next action: stop sequence, reminder on 1 September.
