Complete Guide: Annual Check-in Due → Auto CSM + Customer Emails with n8n
Every SaaS company loses accounts the same way: a customer signs a 12-month contract, the Customer Success Manager (CSM) sets a mental reminder to "check in before renewal," and eleven months later th
Every SaaS company loses accounts the same way: a customer signs a 12-month contract, the Customer Success Manager (CSM) sets a mental reminder to "check in before renewal," and eleven months later that reminder has evaporated into the churn statistics. The annual check-in — the single highest-leverage retention touchpoint you have — dies because it depends on a human remembering a date buried in a CRM field nobody looks at. This guide shows you how to automate it end-to-end with n8n: a daily cron that queries HubSpot for check-ins due today and fires reminder emails to both the CSM and the customer, with zero spreadsheets and zero manual tracking.
The Problem: Renewal Check-ins Depend on Human Memory
The annual check-in exists to do three things: confirm the customer is getting value, surface expansion opportunities, and remove friction before the renewal conversation. When it happens on time, retention and net revenue retention climb. When it slips, you walk into renewal blind — and blind renewals are the ones you lose.
The failure is structural, not personal. Most teams track check-in dates one of two ways:
- A spreadsheet that a founder or ops lead updates by hand, which drifts out of sync with the CRM within weeks.
- A CRM date field (like
next_check_in_datein HubSpot) that nobody has a system to act on. The date is there; the trigger isn't.
As soon as you pass 30 or 40 accounts, no CSM can hold every check-in date in their head. Dates get missed, check-ins bunch up in the last week before renewal, and the customer feels the neglect. You don't need more discipline. You need the date field itself to do the reminding.
The Solution: A Daily Cron That Reads HubSpot and Emails Both Sides
The mechanics are simple. Once a day, a workflow wakes up, asks HubSpot "which accounts have a check-in due today?", and for every match it sends two emails: one to the assigned CSM ("your annual check-in with Acme Corp is due — here's the context") and one to the customer ("time for your annual review — let's book 30 minutes"). Nothing is stored outside HubSpot. The CRM stays the single source of truth, and the automation is a thin layer on top of it.
The full n8n workflow is five nodes:
- Schedule Trigger — fires the run once per day.
- HubSpot (Search) — pulls deals or companies where the check-in date equals today.
- Loop / Item processing — iterates over each due account.
- Send Email (CSM) — internal reminder with account context.
- Send Email (Customer) — outbound review invitation.
That's the entire system. It runs unattended, costs nothing beyond your existing HubSpot and SMTP accounts, and scales from 10 accounts to 10,000 without changing a line.
Step-by-Step Setup in n8n
Assumes a self-hosted or cloud n8n instance and a HubSpot property that holds the check-in date — we'll call it next_check_in_date on the Company object.
1. Schedule Trigger node. Add a Schedule Trigger as the workflow's entry point. Set the rule to Interval → Days → Every 1 day, and pin the trigger time to a business hour — 08:00 in your CSM team's timezone is ideal, so reminders land at the top of the workday. Confirm the n8n instance timezone under Settings → Timezone matches; a mismatched timezone is the most common reason "due today" queries misfire by a day.
2. HubSpot Search node. Add a HubSpot node, resource Company (or Deal), operation Search. Authenticate with a HubSpot Private App token — under HubSpot Settings, create a private app with the crm.objects.companies.read scope and paste the token into n8n's HubSpot credential. Add a filter group:
- Property:
next_check_in_date - Operator: Equal to
- Value: an expression that resolves to today at midnight UTC. HubSpot date properties store midnight-UTC millisecond timestamps, so use
{{ DateTime.now().setZone('UTC').startOf('day').toMillis() }}. Matching a raw ISO string will silently return zero results — this is the single biggest gotcha in the build.
Request the properties you'll need downstream: company name, domain, the CSM's email (e.g. hubspot_owner_id or a custom csm_email property), and the customer contact email.
3. Handle the CSM owner. If you store the CSM as hubspot_owner_id, add a second HubSpot node (resource Owner, operation Get) to resolve the owner ID into a real email address. If you keep a plain csm_email text property, skip this — you already have what you need.
4. Loop over results. Drop in a Loop Over Items (Split in Batches) node so each due account is processed independently. This keeps one bad record — a company missing a contact email — from aborting the whole run.
5. Send Email nodes. Add two Send Email nodes (SMTP) or Gmail nodes wired off the loop. The first targets the CSM:
- To:
{{ $json.csm_email }} - Subject:
Annual check-in due today: {{ $json.name }} - Body: account name, renewal date, a direct link to the HubSpot record (
https://app.hubspot.com/contacts/<portalId>/company/{{ $json.id }}), and last-touch notes so the CSM walks in prepared.
The second targets the customer with a warm, short invitation to book a review — connect a scheduling link (Calendly, HubSpot Meetings) rather than asking them to reply with availability. Set the From name to the CSM so it reads as a personal note, not a system blast.
6. Test and activate. Temporarily set one company's next_check_in_date to today, run the workflow manually, and confirm both emails arrive. Then toggle the workflow Active so the Schedule Trigger takes over.
The Benefits: Compounding Retention on Autopilot
Once live, this workflow changes the economics of your CS motion:
- Zero missed check-ins. Every account with a date gets a same-day reminder. The touchpoint stops depending on memory.
- The CRM stays the source of truth. No parallel spreadsheet to reconcile. A CSM updates the date in HubSpot and the automation adjusts instantly.
- Both sides are activated. The customer email creates external accountability — customers who receive a review invite book far more often than those waiting on an internal reminder alone.
- It scales for free. The workflow costs the same to run for 5,000 accounts as for 50. Your CS headcount no longer caps how many check-ins actually happen.
- Renewals stop being ambushes. Check-ins land months before renewal, giving you room to fix issues and float expansion while there's still time.
Common Pitfalls (and How to Avoid Them)
Timezone drift. If the n8n instance timezone, the Schedule Trigger, and HubSpot's UTC storage disagree, "due today" queries fire a day early or late. Normalize everything to a single reference — build the search value in UTC (startOf('day')) and set the n8n instance timezone explicitly.
Date-format mismatches. HubSpot date-picker properties are midnight-UTC millisecond epochs, not ISO strings. Filtering with a string returns zero rows and no error, so the workflow looks "working" while doing nothing. Always convert to .toMillis().
Duplicate sends. If the workflow errors midway and you re-run it, accounts already emailed can get a second message. Guard against this by writing a last_check_in_sent timestamp back to HubSpot after each send, and adding that property as a second filter (not equal to today) so re-runs skip already-processed records.
Missing contact emails. Companies without a primary contact will have a blank customer email and the Send node will fail. Add an IF node before the customer email to skip (or route to a "needs data" alert) when the address is empty — and process inside a loop so one gap doesn't kill the batch.
Emails landing in spam. A raw SMTP relay with no authentication gets filtered fast. Send through an authenticated provider (Gmail, a warmed transactional domain) with SPF and DKIM configured, and keep the customer email plain-text and personal rather than a heavy HTML template.
No visibility when it breaks. A silent daily cron is dangerous — if HubSpot auth expires, you won't notice for weeks. Add an Error Trigger workflow that pings Slack or email whenever the run fails, so a broken integration surfaces the same day.
Wire these six nodes together once and your annual check-in becomes a property in HubSpot that reminds itself. No spreadsheet, no dropped renewals, no CSM carrying dates in their head — just a reliable daily nudge that keeps every account on schedule.
Ja construimos isso pra voce
Nao comece do zero. O Annual Check-in Due → Auto CSM + Customer Emails e um workflow n8n pronto para instalar — conecta suas ferramentas em minutos, sem codigo.
Instalar por $79 →