Example: Customer support triage

Operations

Watch a support inbox, classify each new message into a category, draft a reply, and either auto-send routine answers or hand off to a human reviewer for sensitive ones.

The flow

  1. Open a WebSocket subscribed to the support inbox's message.received events.
  2. For each new message: read the body, run an LLM classifier ("billing" / "bug" / "feature request" / "general").
  3. For low-risk categories ("general", "FAQ"), draft a reply and auto-send via create_draft + send_draft.
  4. For high-risk categories ("billing", "bug"), draft the reply and notify a human reviewer in your dashboard. The draft persists until they approve.
import WebSocket from "ws";

const ws = new WebSocket("wss://myagentmail.com/v1/ws", {
  headers: { "X-API-Key": process.env.MYAGENTMAIL_KEY! },
});

ws.on("open", () => {
  ws.send(JSON.stringify({
    type: "subscribe",
    event_types: ["message.received"],
    inbox_ids: [process.env.SUPPORT_INBOX_ID!],
  }));
});

ws.on("message", async (raw) => {
  const frame = JSON.parse(raw.toString());
  if (frame.type !== "event" || frame.event_type !== "message.received") return;

  const m = frame.message;
  const category = await classifyWithLLM(m.subject, m.plain_body);
  const replyText = await draftReplyWithLLM(m.subject, m.plain_body, category);

  // Always create a draft first — it's our staging area
  const draft = await mam("POST", `/inboxes/${m.inbox_id}/drafts`, {
    replyToMessageId: m.message_id,
    plainBody: replyText,
  });

  if (category === "general" || category === "faq") {
    // Auto-send routine answers
    await mam("POST", `/inboxes/${m.inbox_id}/drafts/${draft.id}/send`);
  } else {
    // Hand off to a human — record the draft id for the reviewer UI
    await db.createReviewTask({
      inboxId: m.inbox_id,
      draftId: draft.id,
      category,
      originalMessageId: m.message_id,
    });
    await notifySlack(`New ${category} ticket needs review`);
  }
});

The reviewer UI calls GET /drafts/{id} to show the proposed reply, PATCH to edit, and POST /send when satisfied. Drafts let you run a true human-in-the-loop without inventing your own queue.