How to Build n8n Contract Renewal Reminders That Don't Spam Accounts
Build n8n contract renewal reminders with date-math, tiered 90/30/7-day alerts, and a dedupe guard so the daily scan never emails the same account twice.
A customer contract renews in sixty days and nobody's started the conversation. The CSM is heads-down, the renewal date lives in a spreadsheet column nobody sorts by, and the first time anyone notices is the week it lapses. n8n contract renewal reminders turn that silent countdown into a tiered set of nudges that reach the right person early enough to actually save the account.
Most of what ranks here is pointed at the wrong team. n8n's vendor contract renewals template is built for procurement chasing their vendors, single-trigger, no dedupe. ClearContract's renewal-automation walkthrough and Invulnerable's expiring-contract-alerts use case describe the general idea. None of them handle the customer-success angle with the two pieces that make a daily scan livable: tiered thresholds, and a dedupe guard so the same account isn't pinged every morning for a month.
The dedupe guard is the feature
Here's the opinion that decides whether this workflow ships or gets disabled in week one: a renewal reminder without a sent-tier guard is a spam machine. A naive daily Cron that emails every account inside 30 days will email each of them every day for thirty days. The account owner mutes the alerts by day three, and now the automation is worse than nothing, because everyone's learned to ignore it. Tier the reminders, track which tier each account has received, and send each one exactly once.
That's the whole difference between a tool people trust and noise they filter.
What you can automate in renewal reminders
- Scan every active contract once a day for upcoming renewals
- Compute days-until-renewal as a clean integer per account
- Fire tiered alerts at 90, 30, and 7 days before the date
- Route each tier to the right owner (CSM at 90, manager at 30)
- Track which reminder tier each account has already received
- Draft the renewal outreach with the account's context filled in
- Log every reminder for an auditable renewal trail
The date-math and the sent-tier tracking are the two steps the ranking templates skip. They're also the two that keep the inbox sane.
The renewal-reminder pipeline
Schedule (Cron, daily 6am)
→ Read active contracts (Sheets / CRM)
→ Code (days_until_renewal per record)
→ Switch (90 / 30 / 7 day tier)
→ IF tier already sent? → skip
→ Send + route by tier
→ Stamp last_reminder on the record
Scan, compute, tier, guard, send, stamp. The guard before the send is what stops the daily repeat.
1. Scan on a schedule
A Cron trigger firing once a day (6am is the common choice, before anyone's working the accounts) reads the active contracts from wherever they live, a Google Sheet, a CRM custom object, a database. Pull the renewal date, the account owner, and a last_reminder field you'll maintain.
Daily is the right cadence. Hourly is pointless for a date that moves once a day, and it just multiplies the chances of a dedupe slip.
2. Compute days-until-renewal once
The date-math the descriptive guides hand-wave. Do it in one Code node so every threshold check reads the same number:
const MS_DAY = 86400000;
const today = new Date(); today.setHours(0,0,0,0);
return $input.all().map(item => {
const renew = new Date(item.json.renewal_date);
const days = Math.round((renew - today) / MS_DAY);
return { json: { ...item.json, days_until_renewal: days } };
});
Now days_until_renewal is an integer you branch on cleanly. Negative means already lapsed, which is its own (urgent) branch.
3. Tier with a Switch
A Switch node maps the day count to a tier. The standard ladder for B2B contracts: 90 days to open the renewal conversation, 30 days to escalate to the account owner, 7 days as the final internal alert. Match on a small window around each (say 88 to 92 for the 90-day tier) so a record that's scanned a day late still catches its tier instead of falling through the gap.
days <= 7 → tier 7 (final internal alert)
days <= 30 → tier 30 (escalate to owner)
days <= 90 → tier 90 (open the conversation)
Evaluate tightest-first so a 5-day contract hits tier 7, not tier 90.
4. The sent-tier guard
This is the node that makes the daily scan survivable. Read last_reminder off the record. If the account has already received the tier this run would send, skip it:
const due = $json.tier; // 90, 30, or 7
const sent = Number($json.last_reminder || 999);
// only send if we haven't already sent this tier or a closer one
if (sent <= due) return []; // already nudged at this tier or nearer
return [{ json: $json }];
Without this, the account inside the 30-day window gets pinged every morning. With it, the 30-day reminder fires once, the day the account crosses 30, and stays quiet until the 7-day tier comes due. Stamp last_reminder to the tier you just sent, after the send succeeds.
5. Send and route by tier
Each tier goes to a different recipient with different urgency. The 90-day reminder might draft a friendly "let's talk renewal" email to the CSM; the 30-day escalates to the account owner with the account's usage context; the 7-day is an internal Slack alert, not a customer email. An OpenAI node can draft the outreach with the account name, contract value, and tenure filled in, so the CSM edits rather than writes from scratch.
Implementation patterns
Pattern A — the at-risk weighting. Not every renewal deserves the same energy. Cross-reference the renewal scan with a health signal (usage trend, support-ticket volume, last login) and bump at-risk accounts to an earlier, louder tier. A healthy account at 30 days needs a polite nudge; a quiet, declining account at 90 days needs the CSM on a call this week. Generic date-only reminders treat both the same, which wastes attention on the safe ones and under-serves the shaky ones.
Pattern B — the lapsed-contract catch. A separate branch for days_until_renewal < 0 fires an urgent escalation, because a contract that slipped past its date is revenue actively leaking. Most reminder workflows only look forward and never notice the one that already lapsed. The negative branch is cheap and catches the most expensive miss.
The reason renewal-reminder automations get switched off isn't that they fail to send. It's that they send too much. One untiered alert that repeats daily teaches the account owner to ignore renewal pings entirely, which is the exact opposite of the goal. Three tiers, each fired once, each routed to the person who should act at that distance from the date: that's an automation a CS team keeps. Track the sent tier per account and the daily scan stays quiet until it has something new to say.
n8n nodes you'll use most
| Node | Purpose |
|---|---|
| Schedule (Cron) | Daily scan of active contracts |
| Google Sheets / CRM | Read renewal dates, owners, and last_reminder |
| Code | Compute days_until_renewal once per record |
| Switch | Map the day count to the 90 / 30 / 7 tier |
| IF | The dedupe guard, skip tiers already sent |
| OpenAI | Draft renewal outreach with account context |
| Gmail / Slack | Route each tier to the right owner |
Getting started
- Set a Cron trigger for a daily early-morning scan.
- Read active contracts with renewal date, owner, and a last_reminder field.
- Compute days_until_renewal in one Code node so every check agrees.
- Tier the count with a Switch, evaluating tightest threshold first.
- Add the sent-tier guard so each tier fires once per account.
- Route and send per tier, then stamp last_reminder after success.
- Add the at-risk weighting and the lapsed-contract branch.
For the customer-side renewal and retention motion this feeds, the Membership Churn Recovery Engine template scores every account daily for risk and fires AI-personalized retention emails by tier, the same scan-score-tier-send rhythm a renewal workflow runs. If your renewals are subscription billing rather than contracts, the Smart Subscription Manager template audits active Stripe subscriptions and schedules a review.
Browse the customer-success templates →The Membership Churn Recovery Engine template ships the daily-scan-and-tiered-outreach core of this workflow: it scores each member for risk every day, an OpenAI node writes the retention email keyed to the member's tier, and results log to Google Sheets and Slack, so you adapt the scoring input to renewal dates instead of building the scan and dedupe from scratch. It's part of The Complete n8n Templates Bundle, a one-time lifetime license to the whole catalog plus future templates, worth it once you run more than one renewal or retention automation.
A renewal you see coming ninety days out is a renewal you keep. Compute the date-math cleanly, tier the reminders to match how urgency builds, and guard against the daily repeat so the alerts stay worth reading. The same accounts you're renewing are the ones worth watching for churn signals, covered in How to Predict Churn with an n8n Customer Health Score, and the quiet ones are what How to Prevent Churn with n8n addresses head-on. Scan daily, tier the nudges, send each once.
Start with the Membership Churn Recovery Engine →Common questions
How do I calculate days until renewal in an n8n workflow?
How do I stop n8n from sending the same renewal reminder every day?
What renewal reminder thresholds should an account manager use?
Get the workflow templates this guide is built on
Import-ready n8n JSON, step-by-step setup, and tested end-to-end. One-time payment, own it forever.
Get 3 tested n8n templates, free
The full customer package for three real catalog templates — workflow JSON, step-by-step setup guide, credential checklist. Built through the same live-instance release process as everything we sell. Plus new templates and automation guides in your inbox. No spam, unsubscribe anytime.
- 01Smart To-Do List ManagerPre-built n8n workflow template that automates productivity with OpenAI. Live in about 10 minutes.$14
- 02Email Follow-Up AutomatorPre-built n8n workflow template that automates crm with OpenAI. Live in about 15 minutes.$12
- 03Market Trend AnalyzerPre-built n8n workflow template that automates data processing with OpenAI. Live in about 10 minutes.$14
More automation guides

How to Build n8n Deal Stage Automation Without Re-Firing on Itself
A deal moves to "Proposal Sent" and four things should happen: a follow-up task spawns, the AE's manager gets a heads-up, a contract template drafts, and a timer starts so a quiet week triggers a nudg…

How to Automate Sales Call Notes With n8n and Write Them to Your CRM
The call ends, the rep means to log it, and forty other things happen first. Three days later the deal has a one-line note that says "good call, follow up" and nothing about the budget objection that…

How to Build n8n Meeting Scheduling Automation for Sales Teams
A booking link solves half the scheduling problem and quietly creates the other half. The prospect picks a slot, sure. But now that slot has to land on the right rep's calendar, create or update a CRM…