When a prospect replies to one of your campaign emails, Leadterra automatically classifies the intent of their message — interested, not interested, out of office, and more — so your agents or automations can take the right action without manual triage. This guide shows you how to poll for replies, interpret classifications, and route them into downstream workflows.
Poll for replies
Call GET /v1/replies to retrieve all classified replies across your workspace. Responses are paginated and sorted by receivedAt descending, so the most recent replies always appear first.
curl https://app.leadterra.co/v1/replies \
-H "Authorization: Bearer sk_live_YOUR_KEY"
To narrow results to a single campaign, append the ?campaignId= query parameter:
curl "https://app.leadterra.co/v1/replies?campaignId=camp_01HZA1TPNQ8RD4KF" \
-H "Authorization: Bearer sk_live_YOUR_KEY"
A successful response returns an array of reply objects, each enriched with Leadterra’s classification:
{
"replies": [
{
"id": "rpl_01HZB3MNPW6XT8QA",
"email": "ava@acmecorp.com",
"campaignId": "camp_01HZA1TPNQ8RD4KF",
"classification": "interested",
"receivedAt": "2025-06-11T09:14:32Z",
"threadSnippet": "Hey, this actually looks relevant — can we jump on a call Thursday afternoon?"
},
{
"id": "rpl_01HZB3MNPW6XT9RB",
"email": "marcus@buildfast.io",
"campaignId": "camp_01HZA1TPNQ8RD4KF",
"classification": "out_of_office",
"receivedAt": "2025-06-11T08:47:10Z",
"threadSnippet": "I'm out of office until June 16. For urgent matters, please contact..."
}
],
"pagination": {
"total": 2,
"page": 1,
"perPage": 50
}
}
Act on classifications
Leadterra’s classification field lets you branch your logic without building a custom NLP layer. The most common classifications you’ll encounter are:
| Classification | Meaning |
|---|
interested | Prospect expressed positive intent or requested a meeting |
not_interested | Prospect declined or asked to stop outreach |
out_of_office | Auto-reply indicating temporary absence |
referral | Prospect redirected you to a colleague |
question | Prospect asked a clarifying question |
Use the classification field to route each reply to the appropriate handler in your application or agent:
async function handleReply(reply) {
switch (reply.classification) {
case "interested":
// Book a meeting slot and notify the sales rep
await crm.createOpportunity({ email: reply.email, source: "leadterra" });
await calendar.proposeSlot({ email: reply.email });
break;
case "not_interested":
// Respect the opt-out — suppress the address globally
await fetch("https://app.leadterra.co/v1/suppression-list", {
method: "POST",
headers: {
"Authorization": "Bearer sk_live_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ emails: [reply.email] })
});
break;
case "out_of_office":
// Pause outreach and schedule a follow-up after their return date
await scheduler.snooze({ email: reply.email, days: 7 });
break;
default:
// Route to a human review queue for anything ambiguous
await queue.push({ reply, assignTo: "human-review" });
}
}
Use webhooks for real-time replies
Polling works well for low-volume campaigns or batch processing workflows, but if you need replies routed within seconds of receipt, use the reply.received webhook event instead. Register a webhook endpoint and Leadterra will POST each classified reply to your URL the moment it arrives.
See Register Webhooks for setup instructions and payload examples.
For production workloads, prefer the reply.received webhook over polling. Webhooks give you sub-second delivery latency and eliminate the overhead of scheduling repeated API calls. Polling is best reserved for debugging, backfill jobs, or low-frequency reporting.