Skip to main content
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:
ClassificationMeaning
interestedProspect expressed positive intent or requested a meeting
not_interestedProspect declined or asked to stop outreach
out_of_officeAuto-reply indicating temporary absence
referralProspect redirected you to a colleague
questionProspect 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.