Weekly Digest Emails via API: Batching, Content and Unsubscribe
Build a weekly digest email from your app: aggregating a week of activity, when to send, batching without hitting limits, per-user unsubscribe, and the API.
A weekly digest is the email that turns a rarely-opened product into one people remember exists. It is also the first email in most apps that is sent to everyone at once, which makes it the first one to hit sending limits and spam filters. This guide covers what goes in a good digest, when to send it, how to batch the sends, and how to let people turn it off.
Quick answer
Aggregate one week of activity per user into a handful of numbers and a short list of items they care about, send it on the same weekday each week in the morning of the user's local time zone, skip users with nothing to report, include a one-click unsubscribe that works without login, and send from a background queue that spreads the batch over an hour rather than a burst.
What makes a digest worth opening
- Three to five numbers at the top: new signups, revenue, tasks completed, whatever the product is about. Compare to last week.
- A list of items that need the reader, such as unanswered comments or overdue tasks, capped at ten with a "view all" link.
- Something new: a feature, a tip. One paragraph, not a newsletter.
- A link for every item, deep into the app, that works when logged out (send to login, then back).
- Nothing at all if the week was empty. An email that says "nothing happened" is an unsubscribe request in disguise.
Building the data
- Compute per-user aggregates in a job that runs before the send, and store them in a digest_runs table with the user id, week, and the rendered figures. Do not query live data during the send loop.
- Decide per user whether the digest is worth sending: a minimum activity threshold, plus the unsubscribed flag.
- Render HTML from the stored aggregates with your normal template engine. Keep it under 100 KB.
- Enqueue one send job per user with the rendered HTML and text.
- Record message ids and outcomes on the digest_runs row so support can find the delivery log later.
The send request
const res = await fetch("https://api.oqumail.com/api/v1/emails", {
method: "POST",
headers: {
"Authorization": "Bearer " + process.env.OQUMAIL_API_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({
from: "digest@yourdomain.com",
to: user.email,
subject: "Your Acme week: 12 new customers, 3 comments waiting",
html: digestHtml + '<p style="font-size:12px;color:#666"><a href="' + unsubUrl + '">Stop weekly digests</a> or <a href="' + prefsUrl + '">change email settings</a></p>',
text: digestText + "\nStop weekly digests: " + unsubUrl
})
});
if (!res.ok) throw new Error("send failed: " + res.status);Batching and pacing
Sending 5,000 digests in a ten-second burst looks like a spam run to receivers and will hit rate limits on any provider. Put every send into a queue and process it with a small number of workers and a fixed pace, for example 2 to 5 sends per second, so a batch of 5,000 takes 20 to 40 minutes. Group by recipient time zone so each user gets the email around 8 a.m. local time. Respect a 429 response by backing off for a minute; respect a daily limit by continuing tomorrow rather than dropping the remainder. On OquMail the free plan's fair-use limits suit a small product's digest; if your list is large, keep the send spread out and steady, which is also what protects your domain reputation.
Unsubscribe that actually works
A digest is opted-in product email but it is still recurring, so treat unsubscribe seriously. Put an unsubscribe link in every message that hits a signed URL and turns the digest off without login, in one click, with no "are you sure". Keep a separate preferences page for people who want less frequent digests instead of none. Honour the change before the next run, not the one after. Also send from a dedicated digest@ address so users can filter it, and keep a support@ mailbox on the same domain for replies; OquMail provides both on the same domain with the send API.
Common questions
What day and time is best?
Tuesday to Thursday mornings in the user's time zone are the usual choice for work products; Sunday evening for personal ones. Pick one and keep it; consistency matters more than the exact hour.
Does a digest need an unsubscribe link legally?
If it is purely a summary of the user's own activity in a service they pay for, many jurisdictions treat it as service mail. The moment you add promotional content it is marketing. Include the link regardless; it costs nothing and prevents complaints.
How do I avoid Gmail's Promotions tab?
Keep the digest personal (their numbers, their items), keep images few, avoid marketing language, send from an authenticated domain, and skip empty weeks. Engagement is what keeps you in the primary inbox.
Free business email on your own domain
OquMail gives you up to 15 mailboxes on your domain — free — with guided SPF/DKIM/DMARC, webmail, IMAP/SMTP for any mail app, and a send API. Most teams are live in under fifteen minutes. Start at oqumail.com.
Get started free