← Back to recipes

Personalise donor communications at scale

communicationsintermediateemerging

The problem

You want to send thank you messages, updates, or appeals that feel personal, but you've got thousands of donors. Mail merge handles names, but you want to reference their specific giving history, interests, or connection to your cause. Writing individual messages is impossible at scale.

The solution

Use an LLM to generate personalised messages for each donor based on their data. The AI takes a template and your donor information (giving history, interests, past interactions) and creates a unique message for each person. You review a sample, adjust the prompts, and then generate at scale.

What you get

Individualised messages for each donor that reference their specific giving history, interests, or relationship with you. Messages feel personal rather than mass-produced, without the time cost of writing each one by hand.

Before you start

  • Donor data with relevant personalisation fields (giving history, interests, engagement)
  • An OpenAI or Anthropic API key
  • A clear communication goal (thank you, update, appeal)
  • Your brand voice and any must-include/must-avoid messaging guidelines

When to use this

  • You're sending to hundreds or thousands of donors and want personal touches
  • You have good data about each donor that could inform personalisation
  • Generic mail merge isn't achieving the response rates you want
  • You have time to review and refine the output before sending

When not to use this

  • You're sending to a small list where you could just write personal notes
  • You don't have meaningful data to personalise with (just name and address)
  • Your message is time-critical and you can't review before sending
  • Your donors value authenticity highly and might feel deceived by AI-generated 'personal' messages
  • The relationship is built on personal connection (major donors, long-term supporters) where genuine human attention matters more than efficiency

Steps

  1. 1

    Consider the authenticity question

    Before starting, think about how your donors would feel if they knew their 'personal' message was AI-generated. For mass thank-yous or updates, most people understand efficiency is necessary. For major donors or long-term supporters, a genuine human-written note may matter more than perfect personalisation. Consider whether to disclose AI use (e.g., 'crafted with AI assistance') - transparency builds trust even if the message itself was generated.

  2. 2

    Define what you want to personalise

    What makes a message feel personal for your donors? Referencing their total giving, how long they've supported you, specific campaigns they gave to, events they attended, areas of interest? Make a list of the data points you could use.

  3. 3

    Prepare your donor data

    Export the relevant data for each donor: name, giving summary (first gift date, total given, last gift), interests or campaign history, and anything else you want to reference. Clean it up so the AI has good information to work with.

  4. 4

    Write your base template and guidelines

    Write the message you'd send if you weren't personalising, plus guidelines for the AI: your tone of voice, what to emphasise, what to avoid, how long messages should be. Include a few examples of good personalisation from messages you've written manually.

  5. 5

    Test on a small sample

    Run the personalisation on 10-20 donors first. Read every message carefully. Does it sound like you? Is the personalisation appropriate? Does it hallucinate information you didn't provide? Adjust your prompt based on what you learn.

  6. 6

    Refine edge cases

    What happens for a donor with minimal data? A new donor? Someone who gave once years ago? Make sure the AI handles these gracefully rather than making up details or producing awkward phrasing.

  7. 7

    Generate at scale and review

    Run for your full list. Spot-check a random sample across different donor types. Look for anything that feels off. You don't need to read every message, but you should have confidence in the quality.

  8. 8

    Track response rates(optional)

    Compare open rates, click rates, and response rates against your previous communications. Does personalisation improve engagement? Use what you learn to refine future communications.

Example code

Generate personalised thank you messages

This takes donor data and generates individualised thank you messages. Adapt the prompt to match your voice and what you want to reference.

import pandas as pd
from openai import OpenAI
import time

client = OpenAI()

# Load your donor data
donors = pd.read_csv('donors.csv')

# Your organisation's voice and guidelines
guidelines = """
Voice: Warm and genuine, not corporate. We're grateful, not desperate.
Length: 2-3 short paragraphs
Must include: Thank them for their specific support, mention impact, look forward
Avoid: Asking for more money in thank you messages, generic phrases like "your support means so much"
"""

def generate_thank_you(donor):
    prompt = f"""Write a personalised thank you message for a charity donor.

Guidelines:
{guidelines}

Donor information:
- Name: {donor['first_name']} {donor['last_name']}
- Total given: £{donor['total_given']:,.0f}
- First donation: {donor['first_gift_date']}
- Most recent: {donor['last_gift_date']} (£{donor['last_gift_amount']})
- Number of gifts: {donor['gift_count']}
- Interests: {donor.get('interests', 'Not specified')}

Write a thank you message that feels personal and specific to this donor's history with us. Reference specific details where appropriate but don't list everything - pick what's most meaningful."""

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}]
    )

    return response.choices[0].message.content

# Test on first 5 donors
print("Generating sample messages...\n")
for idx, donor in donors.head(5).iterrows():
    print(f"=== Message for {donor['first_name']} {donor['last_name']} ===")
    message = generate_thank_you(donor)
    print(message)
    print("\n" + "-"*50 + "\n")
    time.sleep(0.5)  # Rate limiting

# Once happy, generate for everyone
# donors['personalised_message'] = donors.apply(generate_thank_you, axis=1)
# donors.to_csv('donors_with_messages.csv', index=False)

Tools

OpenAI APIservice · paid
Visit →
Google Colabplatform · freemium
Visit →
Google Sheetsplatform · free
Visit →

Resources

At a glance

Time to implement
days
Setup cost
low
Ongoing cost
low
Cost trend
decreasing
Organisation size
small, medium, large
Target audience
fundraising, comms-marketing

API costs are ~£0.01-0.05 per message depending on length and model. For 5,000 donors that's £50-250. Test with a small batch first.

Part of this pathway

Written by Make Sense Of It

Last updated: 2024-12-22