n8n Tutorial: API Usage at 80%+ → Timed Upsell Email + HubSpot Log Automation
Your API-metered SaaS has a silent revenue leak: accounts that hit 80% of their plan limit are your hottest upgrade prospects, and almost none of them ever hear from you at the moment it matters. By t
Your API-metered SaaS has a silent revenue leak: accounts that hit 80% of their plan limit are your hottest upgrade prospects, and almost none of them ever hear from you at the moment it matters. By the time your monthly billing report surfaces the overage, the buying signal is cold. This n8n workflow closes that gap. An hourly cron scans usage, finds every account crossing the 80% threshold, sends a contextual upsell email while the pain is fresh, and logs the touch in HubSpot — with frequency capping so no one gets spammed twice in the same week.
The Problem: Upgrade Intent Has a 24-Hour Shelf Life
Usage-based buying intent is perishable. A developer who watches their dashboard tick past 80% is, in that moment, actively worried about hitting a wall — throttled requests, failed jobs, an outage during a demo. That worry is the single best upgrade trigger you will ever get, and it decays fast. Wait until the end-of-month invoice and you're pitching to someone who has already either upgraded manually, rate-limited their own app, or churned in frustration.
Most teams handle this one of three bad ways. They send nothing and leave money on the table. They batch a generic "you're using a lot!" blast once a month, which lands as noise. Or they wire up a hard alert at 100% that reads as a punishment rather than an offer. None of these hit the account at 80% — the sweet spot where there's real urgency but still room to sell an upgrade before anything breaks. And the ones that do try often over-fire: an account bouncing between 79% and 82% all day generates a dozen emails, torches trust, and gets marked as spam.
The Solution: An Hourly Threshold Scanner With a Memory
The workflow runs every hour and does four things in sequence. It pulls current usage for all active accounts from your billing or metering source. It filters to accounts at or above 80% of their plan limit. For each one, it checks a suppression record to confirm they haven't already been emailed in the last N days. Then it sends a personalized upsell email and writes the interaction to HubSpot as a logged engagement, updating the contact or company with the usage percentage and the offer sent.
The two design decisions that make this work are hourly granularity and frequency capping. Hourly means you catch the threshold crossing within 60 minutes instead of 30 days. Frequency capping — a hard rule that any given account can only receive one upsell email per rolling 7-day window — is what separates a helpful nudge from a spam cannon. Without it, an hourly cron on a fluctuating metric is a liability, not an asset.
Step-by-Step Setup in n8n
Here's how the nodes wire together. The whole thing is roughly nine nodes and runs in seconds per cycle.
1. Schedule Trigger. Add a Schedule Trigger node set to "Every Hour." This replaces a raw cron and is the entry point. If your usage data has predictable low-traffic hours, you can narrow the interval, but hourly-around-the-clock is the safe default.
2. Fetch usage data. Use an HTTP Request node (or your billing provider's native node — Stripe, Chargebee, or a Postgres node if metering lives in your own DB) to pull each account's current period usage and plan limit. Return at minimum: account_id, email, current_usage, plan_limit, and plan_name. If your API paginates, loop with the built-in pagination options on the HTTP Request node.
3. Calculate the ratio and filter. Drop in a Code node (or a Set node with an expression) to compute usage_pct = current_usage / plan_limit. Follow it with an IF node — or a Filter node when processing a list — with the condition usage_pct >= 0.8. Only accounts above the line pass through. Consider an upper bound too: excluding accounts already at 100% lets you route those to a different "you're over limit" flow.
4. Check the frequency cap. This is the critical node. Before sending, query HubSpot (via the HubSpot node, "Get" contact) or a small lookup table in a Postgres/Airtable node for a last_upsell_sent_at property on the account. Add an IF node: proceed only if that timestamp is empty or older than 7 days. Accounts that were emailed recently drop out here. If you store state in HubSpot, use a custom contact property; if you want the workflow self-contained, a single Postgres table with account_id and last_sent works perfectly.
5. Build the contextual email. Use a Set or Code node to assemble the message with real numbers: "You've used {{$json.current_usage}} of your {{$json.plan_limit}} {{$json.plan_name}} requests this cycle — that's {{Math.round($json.usage_pct*100)}}%." Specificity is what makes this convert. Reference the exact plan they'd upgrade to and a one-click checkout link.
6. Send it. Connect a Send Email (SMTP) node, or a Gmail, SendGrid, or Postmark node depending on your stack. Use a transactional sender, not your marketing domain, so these land in the primary inbox. Set a recognizable from-name — ideally a real person on your team.
7. Log to HubSpot and stamp the cap. Finish with a HubSpot node that creates an Engagement (type: Email/Note) on the contact and updates two properties: last_upsell_sent_at to {{$now}} and last_usage_pct to the current value. The timestamp write is what feeds step 4 on the next run — it's what makes the frequency cap actually hold. Add an Error Trigger or configure "Continue On Fail" on the email and HubSpot nodes so one bad record doesn't halt the batch.
Why This Beats Manual Outreach and Monthly Reports
The obvious win is timing: you reach the account inside an hour of the buying signal instead of weeks later. But the compounding benefits are quieter. Every send is logged in HubSpot, so your sales team sees a live record of usage-driven intent and can follow up on high-value accounts personally. The last_usage_pct property becomes a segmentation asset — you can build lists of accounts trending toward their limit and forecast expansion revenue.
Because it's fully automated, it scales from 50 accounts to 50,000 without adding a minute of human work, and it runs consistently — no one forgets to send it, no rep cherry-picks only the accounts they like. And the frequency cap means the whole thing stays inside deliverability guardrails: one email per account per week, contextual and useful, is the opposite of the batch-and-blast that gets domains blacklisted. This is expansion revenue captured on autopilot, at the exact moment your customer is most willing to pay for it.
Common Pitfalls to Avoid
Firing on flapping metrics. Usage that oscillates around 80% will re-trigger every hour if you skip the frequency cap. The 7-day suppression window is non-negotiable — build and test it before you ever enable the email node.
Writing the timestamp too late. If the HubSpot update runs only after a successful send and the send fails, the cap never sets and the account gets hit again next hour. Set "Continue On Fail" thoughtfully, and consider writing the suppression stamp immediately before the send rather than after.
Emailing accounts already on your top plan. There's nothing to upsell an enterprise account into. Add a filter excluding accounts whose plan_name is your highest tier — route them to a "let's talk about a custom limit" sales alert instead.
Timezone-blind sending. An hourly cron will happily email someone at 3 a.m. their time. Add a Code-node check on the recipient's timezone, or queue off-hours matches and release them during business hours.
No test mode. Before going live, point the email node at your own inbox and run the workflow manually against a handful of real accounts. Confirm the numbers render correctly and the cap holds on a second run. A miswired upsell that spams your best customers costs more than the revenue it was meant to capture.
Ja construimos isso pra voce
Nao comece do zero. O API Usage at 80%+ → Timed Upsell Email + HubSpot Log e um workflow n8n pronto para instalar — conecta suas ferramentas em minutos, sem codigo.
Instalar por $29 →