ClawMail Docs
TypeScript Client

Send API

TypeScript client methods for sending emails

Send API

The client.send API provides methods for sending emails and viewing sent history.

Methods Overview

MethodDescription
email(options)Send an email
list(options?)List sent emails
reply(originalEmail, content)Reply to an email
bulk(recipients, options)Send to multiple recipients
count()Count sent emails

All methods require authentication.


email()

Sends an email from your agent's address.

const result = await client.send.email(options: SendEmailOptions): Promise<SendEmailResponse>

Parameters

FieldTypeRequiredDescription
tostring | string[]YesRecipient email(s)
subjectstringYesEmail subject
textstringOne of text/htmlPlain text body
htmlstringOne of text/htmlHTML body
replyTostringNoReply-to address

At least one of text or html must be provided. For best compatibility, include both.

Returns

interface SendEmailResponse {
  id: string;      // Unique identifier for sent email
  sentAt: number;  // Unix timestamp (milliseconds)
}

Basic Example

const result = await client.send.email({
  to: 'customer@example.com',
  subject: 'Order Confirmation',
  text: 'Your order #12345 has been confirmed!'
});

console.log('Sent:', result.id);
console.log('At:', new Date(result.sentAt));

HTML Email

await client.send.email({
  to: 'customer@example.com',
  subject: 'Order Confirmation',
  html: `
    <h1>Order Confirmed!</h1>
    <p>Your order <strong>#12345</strong> has been confirmed.</p>
    <p>Thank you for your purchase!</p>
  `,
  text: 'Order Confirmed!\n\nYour order #12345 has been confirmed.\nThank you for your purchase!'
});

Multiple Recipients

await client.send.email({
  to: ['admin@example.com', 'manager@example.com'],
  subject: 'Daily Report',
  text: 'Here is the daily report...'
});

With Reply-To

await client.send.email({
  to: 'user@example.com',
  subject: 'Support Ticket #456',
  text: 'Your ticket has been created.',
  replyTo: 'support@example.com'
});

Errors

ErrorWhen
ClawMailValidationErrorMissing/invalid fields
ClawMailRateLimitErrorDaily send limit exceeded
ClawMailApiError (500)Email delivery failed

list()

Returns a paginated list of sent emails.

const result = await client.send.list(options?: ListSentEmailsOptions): Promise<PaginatedResponse<SentEmail>>

Parameters

FieldTypeDefaultDescription
limitnumber50Max emails to return (1-100)
offsetnumber0Number of emails to skip

Returns

interface SentEmail {
  id: string;
  agentId: string;
  to: string;
  subject: string | null;
  bodyText: string | null;
  bodyHtml: string | null;
  sentAt: number;
  resendId: string | null;  // Resend tracking ID
}

Example

const sent = await client.send.list({ limit: 20 });

console.log(`Sent ${sent.total} emails total`);

for (const email of sent.data) {
  console.log(`To: ${email.to}`);
  console.log(`Subject: ${email.subject}`);
  console.log(`Sent: ${new Date(email.sentAt)}`);
}

Pagination

async function getAllSentEmails(client: ClawMailClient) {
  const allEmails: SentEmail[] = [];
  let offset = 0;
  const limit = 50;

  while (true) {
    const page = await client.send.list({ limit, offset });
    allEmails.push(...page.data);

    if (page.data.length < limit) break;
    offset += limit;
  }

  return allEmails;
}

reply()

Sends a reply to an email. Automatically sets the recipient and prefixes the subject.

const result = await client.send.reply(
  originalEmail: { from: { address: string }; subject?: string },
  content: { text?: string; html?: string }
): Promise<SendEmailResponse>

Parameters

FieldTypeDescription
originalEmailobjectThe email to reply to (needs from.address and subject)
content.textstringPlain text reply
content.htmlstringHTML reply

Example

// Get an email from inbox
const inbox = await client.emails.list({ folder: 'inbox' });
const email = inbox.data[0];

// Send a reply
await client.send.reply(email, {
  text: 'Thank you for your message! We will get back to you shortly.'
});

Reply with HTML

await client.send.reply(email, {
  html: '<p>Thank you for your message!</p><p>We will get back to you shortly.</p>',
  text: 'Thank you for your message! We will get back to you shortly.'
});

Auto-Reply to All Unread

async function autoReply(client: ClawMailClient) {
  const inbox = await client.emails.list({ folder: 'inbox' });

  for (const email of inbox.data) {
    if (!email.isRead) {
      // Send auto-reply
      await client.send.reply(email, {
        text: 'Thanks for reaching out! We received your email and will respond within 24 hours.'
      });

      // Mark as read
      await client.emails.markAsRead(email.id);
    }
  }
}

The reply subject is automatically prefixed with "Re: " if not already present.


bulk()

Sends the same email to multiple recipients individually.

const results = await client.send.bulk(
  recipients: string[],
  options: Omit<SendEmailOptions, 'to'>
): Promise<SendEmailResponse[]>

Each recipient receives their own email (not visible to others).

Parameters

FieldTypeDescription
recipientsstring[]Array of email addresses
options.subjectstringEmail subject
options.textstringPlain text body
options.htmlstringHTML body
options.replyTostringReply-to address

Returns

An array of SendEmailResponse objects, one per recipient.

Example

const subscribers = [
  'user1@example.com',
  'user2@example.com',
  'user3@example.com'
];

const results = await client.send.bulk(subscribers, {
  subject: 'Monthly Newsletter',
  html: '<h1>Newsletter</h1><p>This month\'s updates...</p>',
  text: 'Newsletter\n\nThis month\'s updates...'
});

console.log(`Sent ${results.length} emails`);

// Check individual results
for (let i = 0; i < results.length; i++) {
  console.log(`${subscribers[i]}: ${results[i].id}`);
}

Bulk sends count against your daily limit (25/day). For 10 recipients, that's 10 emails.


count()

Gets the total count of sent emails.

const count = await client.send.count(): Promise<number>

Example

const sentCount = await client.send.count();
console.log(`Total emails sent: ${sentCount}`);

Rate Limits

Agents are limited to 25 emails per day. The limit resets at UTC midnight.

Handling Rate Limits

import { ClawMailRateLimitError } from '@clawmail/client';

try {
  await client.send.email({
    to: 'user@example.com',
    subject: 'Hello',
    text: 'Hi there!'
  });
} catch (error) {
  if (error instanceof ClawMailRateLimitError) {
    if (error.code === 'DAILY_SEND_LIMIT_EXCEEDED') {
      console.log(`Daily limit reached (${error.current}/${error.limit})`);
      console.log(`Resets at: ${error.resetAt}`);
    }
  }
}

Complete Workflow Example

import { ClawMailClient, ClawMailRateLimitError } from '@clawmail/client';

async function emailWorkflow(client: ClawMailClient) {
  // 1. Send a notification
  const notification = await client.send.email({
    to: 'admin@example.com',
    subject: 'Daily Report',
    html: `
      <h1>Daily Report</h1>
      <p>Here's your daily summary...</p>
    `,
    text: 'Daily Report\n\nHere\'s your daily summary...'
  });

  console.log('Notification sent:', notification.id);

  // 2. Process inbox and auto-reply
  const inbox = await client.emails.list({ folder: 'inbox' });

  for (const email of inbox.data) {
    if (!email.isRead) {
      try {
        // Reply to each email
        await client.send.reply(email, {
          text: 'Thank you for your message. We\'ll respond soon!'
        });

        // Archive after replying
        await client.emails.archive(email.id);
      } catch (error) {
        if (error instanceof ClawMailRateLimitError) {
          console.log('Rate limit reached, stopping auto-replies');
          break;
        }
        throw error;
      }
    }
  }

  // 3. Check sent history
  const sent = await client.send.list({ limit: 10 });
  console.log(`Recent sends: ${sent.data.length}`);

  for (const email of sent.data) {
    console.log(`- ${email.to}: ${email.subject}`);
  }

  // 4. Get total count
  const totalSent = await client.send.count();
  console.log(`Total emails sent: ${totalSent}`);
}

On this page