Email Campaigns

Campaigns send individual, personalised emails to a list of recipients — all tracked under a shared batch ID.

Creating a campaign

A campaign send (type: "campaign") sends one individual email per recipient rather than a single email to all recipients together. Each send is tracked with a shared batchId.

Via the API

import { RemindMe } from 'remindme-sdk';

const client = new RemindMe('dm_live_your_api_key');

const result = await client.send({
  from: 'newsletter@acme.com',
  to: [
    'alice@example.com',
    'bob@example.com',
    'carol@example.com',
  ],
  subject: 'Our monthly update',
  html: '<h1>Hello!</h1><p>Here is what happened this month...</p>',
  type: 'campaign',   // ← key difference from transactional
});

console.log(result.batchId);    // shared batch ID
console.log(result.messageIds); // one messageId per recipient

Transactional vs. Campaign

TransactionalCampaign
Emails sent1 (all recipients in To)1 per recipient
Recipients see each otherYes (in To header)No
batchId returnedNoYes
messageIds returnedNo (single messageId)Yes (one per recipient)
Best forNotifications, receiptsNewsletters, outreach

Mail merge & personalization

Because each campaign email is rendered and sent individually, you can personalise the HTML body per recipient before calling client.send().

RemindMe does not yet have a built-in template engine — personalisation is done in your application code before you call the API. A simple pattern using a helper function:

import { RemindMe } from 'remindme-sdk';

const client = new RemindMe('dm_live_your_api_key');

const recipients = [
  { email: 'alice@example.com', name: 'Alice' },
  { email: 'bob@example.com',   name: 'Bob' },
];

// Send one personalised email per recipient
for (const { email, name } of recipients) {
  await client.send({
    from: 'hello@acme.com',
    to: email,
    subject: `Hey ${name}, check this out`,
    html: `<p>Hi ${name},</p><p>We have something just for you!</p>`,
    type: 'campaign',
  });
}
For large lists, batch the sends and add a small delay between requests to avoid hitting rate limits.

Scheduling & auto follow-ups

Use the scheduledAt field to schedule a campaign for a future time. Pass a Unix millisecond timestamp. The value must be in the future.

const ONE_HOUR = 60 * 60 * 1000;

await client.send({
  from: 'newsletter@acme.com',
  to: ['alice@example.com', 'bob@example.com'],
  subject: 'Scheduled newsletter',
  html: '<p>This was scheduled!</p>',
  type: 'campaign',
  scheduledAt: Date.now() + ONE_HOUR, // send in 1 hour
});

// status will be "scheduled" instead of "queued"

Auto follow-ups

Automatic follow-up sequences can be implemented in your own application by scheduling subsequent sends with increasing scheduledAt values:

const DAY = 24 * 60 * 60 * 1000;
const now = Date.now();

// Initial email
await client.send({ ..., scheduledAt: now + DAY });

// Follow-up 3 days later
await client.send({
  ...,
  subject: 'Following up!',
  scheduledAt: now + 4 * DAY,
});

Campaign analytics

Each campaign send returns a batchId and an array of messageIds (one per recipient). Use these to track delivery in the dashboard.

Navigate to Dashboard → Campaigns and enter your batchId to see:

  • Total recipients
  • Delivery status per message (queued, sent, bounced)
  • Open and click tracking (on supported plans)
  • Bounce and complaint rates
Open and click tracking requires a tracking domain to be configured. This is available on the Pro plan and above.