Skip to main content

Bulk Campaigns from CRM / CSV

Use this guide to send large, personalised postal campaigns from your CRM or database using the Intelliprint hybrid mail API. Typical examples:
  • Renewal and upgrade campaigns
  • Seasonal offers and discounts
  • Customer reactivation campaigns
  • Regulatory or terms updates

High-Level Flow

You:
  1. Export contacts and variables from your CRM as CSV.
  2. Convert the CSV into an Intelliprint mailing_list.
  3. Design a template with variables in the Intelliprint dashboard.
  4. Trigger a single print job that sends personalised letters to everyone.

Step 1: Export Contacts and Variables

From your CRM or database, export:
  • Recipient names and postal addresses
  • Variables you want to personalise (e.g. first_name, discount_code, expiry_date, tier)
Example CSV columns:
name,address_line,postcode,country,first_name,salutation,discount_code,tier
John Doe,123 High Street,SW1A 1AA,GB,John,Mr.,SAVE20,Gold
Jane Smith,456 Market Road,M1 1AA,GB,Jane,Ms.,SAVE10,Silver

Step 2: Create a Mailing List from CSV

Use the pattern from the Mailing List + Template quickstart to create a mailing list from your CSV export.
import fs from "fs";
import { parse } from "csv-parse/sync";
import Intelliprint from "intelliprint";

const ip = Intelliprint(process.env.INTELLIPRINT_API_KEY);

async function importCsvToMailingList(csvPath) {
  const csvContent = fs.readFileSync(csvPath, "utf-8");
  const records = parse(csvContent, { columns: true, skip_empty_lines: true });

  const recipients = records.map((row) => ({
    address: {
      name: row.name,
      line: row.address_line,
      postcode: row.postcode,
      country: row.country || "GB"
    },
    variables: {
      first_name: row.first_name,
      salutation: row.salutation,
      discount_code: row.discount_code,
      tier: row.tier
    }
  }));

  const mailingList = await ip.mailingLists.create({
    name: "Winter Upgrade Campaign",
    recipients
  });

  console.log(`✓ Imported ${recipients.length} recipients`);
  console.log("Mailing list ID:", mailingList.id);

  return mailingList.id;
}

Step 3: Design a Template in the Dashboard

In the Intelliprint dashboard:
  1. Go to Templates → Create new template.
  2. Add variables that match your CSV columns, for example:
<h1>Dear {salutation} {first_name},</h1>
<p>As a valued {tier} customer, we have a special offer for you.</p>
<p>Use discount code <strong>{discount_code}</strong> before the expiry date.</p>
  1. Save the template and note the template ID (e.g. tmpl_abc123).
Variables in dashboard templates are replaced automatically for each recipient in your mailing list.

Step 4: Trigger the Campaign via the API

Use a single API call to send personalised letters to all recipients in the mailing list:
async function sendCampaign(mailingListId) {
  const printJob = await ip.prints.create({
    testmode: true,            // keep true while testing
    template: "tmpl_abc123",   // your dashboard template ID
    mailing_list: mailingListId,
    confirmed: true
  });

  console.log("✓ Campaign print job created:", printJob.id);
  console.log("Total letters:", printJob.letters.length);

  return printJob.id;
}
When you are ready to go live, remove testmode or set it to false.

Step 5: Monitor Results

Use the dashboard and API to:
  • Confirm how many letters were created and posted.
  • See per-letter statuses and any failed or returned mail.
  • Export lists for follow-up (e.g. customers who did not respond).
Key docs: You can also add campaign identifiers into metadata:
const printJob = await ip.prints.create({
  testmode: true,
  template: "tmpl_abc123",
  mailing_list: mailingListId,
  metadata: {
    campaign_name: "winter_upgrade_2025",
    segment: "existing_customers"
  },
  confirmed: true
});

Performance, Costs & Best Practices

  • Use templates + mailing lists for 100–10,000+ recipients.
  • Use address validation for large campaigns where deliverability matters.
  • Use double-sided printing for longer letters to reduce sheet count.
See:

Next Steps