1. Features
  2. AI
AI

Know what each reply means, and draft the next one.

Two optional features: classifying replies to the mail you send, and drafting email text for a person to edit. Both are off until you turn them on, and send only the text a feature needs to our AI gateway.

message.classified
// A reply to one of your sends, as your webhook gets it
{
  "type": "message.classified",
  "data": {
    "classification": {
      "kind": "auto_reply",
      "autoReplyCategory": "left_company",
      "optOutProbability": 0.02,
      "returnDate": null,
      "alternateContacts": ["sam.lee@example.com"],
      "outboxId": "7b9d1f3a-5c7e-4a9b-8d1f-3a5c7e9b1d3f"
    }
  }
}
What you get

Replies sorted, opt-outs handled, drafts on request

Classification runs on replies to your own sends; drafting runs only when someone asks for a draft. Nothing else calls the AI gateway.

Four kinds of reply

Each reply is an opt_out request, an auto_reply, a bounce or a human_reply, with a probability for each kind.

Six auto-reply categories

Out of office, left the company, address changed, ticket acknowledgment, challenge-response, or other. Auto-reply headers are a hint to the classifier, never the verdict.

Return dates

An out-of-office reply's return date is read from its text, resolved against the day it was sent in the sender's time zone. A date that isn't real, falls before the day it was sent, or is more than a year after it is left empty.

People who moved on

When your recipient left the company or changed address, up to five addresses the reply names are kept as alternateContacts, read from the text itself, never from the model.

Opt-outs, your way

A likely opt-out from your own recipient is ignored, held for review, or suppressed, per your opt-out setting. A person approves or dismisses each held review.

Matched to your sends

A reply is tied to the outbox entry it answers through its thread or its In-Reply-To and References headers, and carries that entry's outboxId.

Drafting

Write an email body from instructions, in plain text or Markdown, optionally in reply to a message or reworking a draft. Nothing is sent or saved.

Metered per day

Every answered call, classification or draft, counts toward aiCalls in your daily usage, next to sends and API calls.

Off until you opt in

Reply classification waits for your workspace to turn it on, since reply text goes to a third party. Drafting runs only when someone asks for a draft.

How it works

From a reply in the inbox to a decision

Classification runs after a reply is indexed, takes about a second, and is announced as message.classified.

  1. Matched to a send

    New inbound mail in the inbox or junk that answers a message you sent through workwae is queued. Mail more than seven days old when it's indexed, such as from a widened sync window, is history and isn't classified.

  2. Classified

    One decision gives the kind, the opt-out probability and, for an auto-reply, its category. An out-of-office reply is read once more for its return date.

  3. Handled

    The result is stored as the message's classification. Opt-outs and recipients who moved on go to your opt-out setting.

Opt-out handling

What a detected opt-out does

Your workspace's optOutHandling setting decides, review by default. It applies to replies from the send's own recipient; an opt-out counts at a probability of 0.9 or more.

Opt-out handling modes
Setting Reply asking to opt out Left the company or changed address
off Ignored. The reply is still classified. Ignored.
review Waits in the review queue with the message it came from and how sure the detection was. Waits for review on the global list (source inactive), with the alternate contacts.
suppress Suppressed at once. Where the send went to several people, it waits for review unless the receiving server shows DMARC, or an aligned SPF or DKIM, passing for the sender. Waits for review. Never suppressed at once.
  • Unsubscribe links and one-click unsubscribe always suppress, whatever the setting says.
  • From anyone other than the send's recipient, a left-the-company or address-changed reply keeps no addresses and queues nothing.
Your data

What goes to our AI gateway, and what doesn't

When a feature is on, workwae sends only the text it needs to Gatewae, the AI gateway we use, which forwards it to a language model provider. The results are returned to your workspace.

Data sent for each AI feature
Feature Sent Not sent
Reply classification The reply's subject, the first 2,000 characters of its own text, and whether it carries standard auto-reply headers. An out-of-office reply's subject and text are sent once more, with the date the reply was sent, to read its return date. Quoted history, the rest of the thread, attachments, and anything about the account or the recipient.
Draft writing The person's instructions, their draft so far and, when answering a message, that message's sender, subject and first 4,000 characters. Anything else in the mailbox. Drafting runs only when a person asks for a draft.
  • No training

    We use only providers that do not use the data we send to train their models, and the data is never used by us to train any model.

  • Documented in our policies

    The same list is in the Privacy Policy, and Gatewae is listed among our subprocessors.

  • Outages delay, they don't lose

    If the gateway or the provider fails, the reply is retried later, backing off to an hour, for up to seven days. Classification catches up on its own.

  • Limits per workspace

    Each workspace has a daily cap on classified replies; past it, replies wait for the next UTC day. Drafts have a per-minute limit, answered with rate_limited and Retry-After.

Build it

Turn it on and work the review queue

Switch on classification for your workspace, pick how opt-outs are handled, and let a person decide on the held ones.

  • Turning it off drops queued replies unread. Nothing is sent once the setting is off.
  • Reviews carry context: the list, the address, the source, the message it came from and how sure the detection was.
  • Approving suppresses the address on the review's list; dismissing drops the review.
settings.ts
await workwae.settings.update({
  aiReplyClassification: true,
  optOutHandling: "review",
});

// Opt-outs and recipients who moved on, waiting for a person
const reviews = workwae.suppressionReviews;
const { items } = await reviews.list({});
for (const review of items) {
  const ok = await askOwner(review.address, review.source);
  const input = { reviewId: review.id };
  await (ok ? reviews.approve(input) : reviews.dismiss(input));
}
Build it

Act on replies as they're classified

Pause a sequence until someone is back, suggest the new contact when someone left, and stop following up once a person answers.

  • Signed and typed. parseWebhook checks the signature and narrows the event on its type.
  • outboxId ties back to the send that got the reply, and the event carries the message and its mailboxes.
  • Categories only on auto-replies. autoReplyCategory is null for every other kind.
webhook.ts
import { parseWebhook } from "@workwae/sdk";

const body = await request.text();
const event = await parseWebhook(secret, request.headers, body);
if (event.known && event.type === "message.classified") {
  const { message, classification: c } = event.data;
  switch (c.autoReplyCategory) {
    case "out_of_office":
      if (c.returnDate) await pause(c.outboxId, c.returnDate);
      break;
    case "left_company":
    case "address_changed":
      await suggest(message.threadId, c.alternateContacts);
      break;
  }
  if (c.kind === "human_reply") await stopFollowUps(c.outboxId);
}
Build it

Draft a reply for a person to edit

POST /v1/ai/draft writes an email body from instructions and returns { text }. The same endpoint powers "Draft with AI" in the console's compose and template editor.

  • Instructions of up to 2,000 characters, in the person's own words.
  • Context, all optional: the message being answered (accountId with replyToMessageId) and the draft so far (currentDraft) to rewrite or continue.
  • Format text or markdown. Needs an API key with the write scope.
  • Clear refusals: ai_refused when the model declines, ai_unavailable when the gateway fails or times out.
draft.ts
import { isApiError } from "@workwae/sdk";

try {
  const { text } = await workwae.ai.draft({
    instructions: "Shorter, and offer a call on Thursday",
    context: {
      accountId,
      replyToMessageId: messageId,
      currentDraft,
    },
    format: "markdown",
  });
  editor.setValue(text);
} catch (error) {
  if (!isApiError(error, "ai_refused")) throw error;
  showHint("Try rewording the request");
}

// AI calls per day, next to the rest of your usage
const { days } = await workwae.usage.get({ from: "2026-10-01" });
const aiCalls = days.map((d) => [d.day, d.aiCalls]);
Events

Events from AI features

Signed webhooks and change-feed entries, like every other event.

Events emitted by AI features
Event When
message.classified A reply to one of your sends was classified. Carries the message, its mailboxes and the classification.
suppression.created A detected opt-out was suppressed, at once or on approval (source reply), or an approved review of a recipient who moved on put the address on the global list (source inactive).
FAQ

Questions about AI features

Is anything sent to the AI gateway by default?

No. Reply classification is off until your workspace turns it on, and drafting runs only when someone asks for a draft. Nothing else calls the gateway.

Is my data used to train models?

No. We use only providers that do not use the data we send to train their models, and the data is never used by us to train any model.

Which replies are classified?

New mail in the inbox or junk that answers a message your workspace sent through workwae, matched by thread or by the Message-IDs its In-Reply-To and References name. Other mail is never classified.

Can I classify replies without suppressing anyone?

Yes. With optOutHandling set to off, replies are still classified and announced, and detected opt-outs are ignored. Unsubscribe links still suppress.

Does drafting send or save anything?

No. The endpoint returns text for a person to edit. Saving it as a draft or sending it is a separate call you make.

What happens when the gateway is down?

Replies are retried later, backing off to an hour, until they are seven days old, so an outage delays classification rather than losing replies. A draft request answers ai_unavailable.

Early access

Let replies sort themselves.

workwae is in early access. Tell us what you are building, and read the docs in the meantime.