Sendr Docs
Guides

Bulk Sending

Send to thousands of recipients efficiently using the batch endpoint and campaigns.

Sendr has two approaches for sending at scale:

ApproachBest forMax per call
Batch endpointTransactional bulk (order updates, notifications)100 emails
CampaignsMarketing broadcasts to audiencesUnlimited (via audience)

Batch endpoint

The /v1/emails/batch endpoint accepts up to 100 emails per request and queues them atomically. All emails in a batch share a default from, subject, and template_id, with per-email overrides.

Basic batch

import { Sendr } from "sendr";

const sendr = new Sendr(process.env.SENDR_API_KEY!);

// Build your list of recipients
const users = [
  { email: "alice@example.com", name: "Alice", orderId: "ORD-001" },
  { email: "bob@example.com", name: "Bob", orderId: "ORD-002" },
  // ... up to 100
];

const { data } = await sendr.emails.sendBatch({
  from: "orders@acme.com",
  subject: "Your order has shipped",
  emails: users.map(user => ({
    to: user.email,
    html: `<p>Hi ${user.name}, order ${user.orderId} has shipped!</p>`,
  })),
});

console.log(`Queued ${data.length} emails`);

Large lists: chunk into batches

function chunk<T>(array: T[], size: number): T[][] {
  const chunks: T[][] = [];
  for (let i = 0; i < array.length; i += size) {
    chunks.push(array.slice(i, i + size));
  }
  return chunks;
}

async function sendToAllUsers(users: User[]) {
  const batches = chunk(users, 100); // Max 100 per batch
  const results: string[] = [];

  for (const batch of batches) {
    const { data } = await sendr.emails.sendBatch({
      from: "hello@acme.com",
      emails: batch.map(user => ({
        to: user.email,
        html: `<p>Hi ${user.name}!</p>`,
      })),
    });
    results.push(...data.map(e => e.id));

    // Brief pause to avoid hitting rate limits
    await new Promise(resolve => setTimeout(resolve, 200));
  }

  return results;
}

Batch with templates

Use template_id for a shared template and variables for per-email substitution:

await sendr.emails.sendBatch({
  from: "hello@acme.com",
  template_id: "tmpl_abc123",
  emails: users.map(user => ({
    to: user.email,
    variables: {
      name: user.name,
      plan: user.plan,
      expiry: user.expiresAt,
    },
  })),
});

Campaigns

For marketing broadcasts to large audiences, use campaigns. Unlike the batch endpoint, campaigns:

  • Target an entire audience (contact list) rather than individual addresses
  • Handle unsubscribes automatically via List-Unsubscribe headers
  • Can be scheduled in advance
  • Provide per-campaign analytics

Campaign workflow

// 1. Create an audience
const audience = await sendr.audiences.create({
  name: "Pro Plan Users",
});

// 2. Add contacts to the audience
await sendr.contacts.bulkImport([
  { email: "alice@example.com", first_name: "Alice" },
  { email: "bob@example.com", first_name: "Bob" },
  // ...thousands more
]);

// 3. Create and schedule the campaign
const campaign = await sendr.campaigns.create({
  name: "March Feature Announcement",
  subject: "New features in March",
  from: "Newsletter <news@acme.com>",
  audience_id: audience.id,
  html: `
    <h1>Here's what's new in March</h1>
    <p>We shipped three major features this month...</p>
  `,
  unsubscribe_url: "https://acme.com/unsubscribe",
  scheduled_at: "2025-03-15T09:00:00Z",
});

console.log(campaign.status); // "scheduled"

// 4. Check stats after sending
const stats = await sendr.campaigns.getStats(campaign.id);
console.log(`Delivered: ${stats.delivered} / ${stats.total}`);
console.log(`Open rate: ${((stats.opened / stats.delivered) * 100).toFixed(1)}%`);

Cancelling a campaign

// Cancel before it starts sending
await sendr.campaigns.cancel(campaign.id);

You cannot cancel a campaign once it has started sending.

Plan limits summary

FeatureFreeProBusinessEnterprise
Monthly emails3,00050,000200,000Unlimited
Marketing emails/month010,00050,000Unlimited
Campaigns325UnlimitedUnlimited
Audiences325UnlimitedUnlimited
Contacts50010,000100,000Unlimited

Free plan does not support marketing emails or campaigns. Upgrade to Pro or higher.

Deliverability tips for bulk sends

  1. Warm up new domains gradually — start with a few hundred emails/day and increase over 2 weeks
  2. Verify your audience — remove hard bounces and inactive addresses before large sends
  3. Use suppression lists — Sendr automatically suppresses hard bounces; check your suppression list before importing
  4. Segment your audience — engaged subscribers have higher open rates, which improves sender reputation
  5. Include a real unsubscribe link — required by CAN-SPAM and GDPR, improves deliverability
  6. Send at consistent times — ISPs look for consistent patterns from legitimate senders

On this page