Free Cold Email Software vs. a Python Script: What You Still Need to Manage

The Sendvanta Team · October 18, 2026 · 10 min read

A Python script can absolutely send cold email. Sending is the easy part — roughly 40 lines with `smtplib` or the Gmail API. What the script doesn't give you is warm-up, bounce parsing, reply threading, suppression, unsubscribe handling, and deliverability monitoring. If you send under a few thousand emails a month, a free platform tier does all of that for $0, which beats both a $97/month plan and maintaining your own code.

This question keeps coming up in outbound communities: someone cancels a $97/month sending tool, builds a script over a weekend, and reports that it works fine. They're usually telling the truth — for about six weeks. Then a mailbox gets rate-limited, a bounce loop burns the domain, or a prospect replies "unsubscribe" and gets follow-up #3 two days later. Below is the honest version of what you're taking on.

ApproachBest forStarting priceWhat you still manage yourself
Python + SMTP/Gmail APIEngineers sending <300/month to a known list$0 (plus your time)Everything: throttling, warm-up, bounces, replies, suppression, auth
Python + transactional ESP (SendGrid, Postmark, SES)Not cold email — these providers' terms prohibit itUsage-basedAccount termination risk on top of everything above
Free tier of a cold email platformSolo founders and small B2B teams under ~3,000 sends/month$0 (Sendvanta free plan)List building, copy, and replies you should answer anyway
Paid cold email platformTeams running multiple domains, mailboxes, or clients$29–$99/mo typicalStrategy and copy

The DIY argument is reasonable — up to a point

The cost math that drives people to scripts is real. A mid-tier plan on one of the big sending platforms runs $90–$100/month, and if you're sending 400 emails a month to a hand-built list, you're paying roughly $0.25 per email for infrastructure you barely use. Scripts also give you things platforms don't: arbitrary personalization logic, direct access to your CRM's database, and no seat limits.

The argument breaks when you confuse *sending* with *running outbound*. The SMTP call is maybe 5% of the work. The other 95% is state management — knowing who got what, when, who replied, who bounced, who opted out, and which mailbox is currently in trouble.

What a script genuinely handles well

  • Templating and merge fields. Jinja2 does this better than most platform editors.
  • Scheduling. `cron` plus a jitter function is fine for sending at randomized intervals.
  • Custom enrichment. Pulling a prospect's latest funding round or tech stack at send time is easier in your own code.
  • Sending to a small, clean, verified list from one mailbox you already trust.

If that's your whole use case — one mailbox, a few hundred verified contacts a month, you personally watching the inbox — a script is a defensible choice. Everything past that is where the list below starts costing you weekends.

1. Per-mailbox limits and throttling

Google Workspace caps at 2,000 messages per day via the Gmail API for paid accounts (500 for trial accounts), and Microsoft 365 enforces 10,000 recipients per day with a 30-messages-per-minute throttle. Those are the hard ceilings. Your practical cold-email ceiling is far lower — 30 to 50 per mailbox per day on a warmed account.

Your script needs a per-mailbox counter that survives restarts, resets on the provider's clock (not yours), backs off on 4.7.x temporary rejections, and distributes sends across a working day rather than firing 50 messages at 09:00. None of that is hard. All of it is state you now own, and a crashed cron job that re-runs the same batch is how people send duplicates to 200 prospects. More on the underlying math in how email throttling and rate limits affect cold outreach.

2. Warm-up

A new mailbox on a new domain with no sending history and no inbound engagement is the single most common reason cold email lands in spam. Warm-up fixes that by generating real, labeled, replied-to messages in the mailbox over several weeks.

You cannot meaningfully script this alone. Warm-up requires a pool of cooperating mailboxes that open, reply, mark-as-important, and rescue from spam. Building that yourself means running dozens of mailboxes purely to talk to each other — which is both expensive and, if done sloppily, a pattern mailbox providers recognize. This is the one item on the list where DIY isn't just more work, it's structurally worse.

3. Bounce parsing

SMTP doesn't always tell you a message failed at send time. Hard bounces often arrive asynchronously as a DSN (RFC 3464 `multipart/report`) in the sending mailbox, minutes or hours later. To handle them you need to poll IMAP, identify DSNs, extract the original recipient and the enhanced status code, distinguish 5.1.1 (no such user) from 4.2.2 (mailbox full, retry later), and suppress the address before the next step in the sequence goes out.

Skip this and your bounce rate compounds silently. Sustained bounce rates above 3–5% are what get a domain throttled. If you're building your own parser, assume a day of work and a long tail of malformed reports from gateways that don't follow the spec.

4. Reply detection, threading, and auto-stop

Two separate problems. Threading: follow-ups need the correct `In-Reply-To` and `References` headers plus a stable `Message-ID` from step one, or Gmail shows each follow-up as a new conversation and the prospect sees three disconnected emails. Auto-stop: when someone replies, every remaining step must halt within minutes, across every mailbox, including when they reply from a different address than the one you sent to.

Then there's classification. An out-of-office auto-reply should not stop the sequence permanently — it should pause it. A bounce notification should not be counted as a reply. A referral ("talk to Dana") needs different handling than a "no thanks." Getting this wrong is what makes DIY outreach feel amateur to the recipient. Our breakdown of classifying positive, negative, referral, and out-of-office replies shows how much nuance is in that bucket.

5. Unsubscribe and suppression

CAN-SPAM requires a working opt-out mechanism and honoring it within 10 business days. Google and Yahoo's bulk sender rules push one-click unsubscribe (`List-Unsubscribe` with `List-Unsubscribe-Post`) for high-volume senders, and recipients increasingly expect it regardless of volume.

So you need: a header, a public endpoint that accepts a POST without authentication, a suppression table, and a check against that table before every single send — including sends from other campaigns, other mailboxes, and other team members. The failure mode isn't theoretical. Emailing someone who opted out is the fastest way to collect a spam complaint, and complaints are weighted far more heavily than bounces by Gmail's reputation systems.

6. Deliverability monitoring and spam scoring

Your script will happily send 400 emails straight into the spam folder and report 400 successes. SMTP 250 OK means accepted for delivery, not delivered to an inbox.

To know what's actually happening you need some combination of: SpamAssassin scoring of drafts before send, seed-mailbox placement tests across Gmail/Outlook/Yahoo, Google Postmaster Tools monitoring, DMARC aggregate report parsing, and blocklist checks. Each is scriptable. Together they're a side project. And unless you also build thresholds that *automatically slow down or pause sending* when the numbers go bad, monitoring just means you find out faster that you've already damaged the domain.

Worth noting too: open tracking numbers you compute yourself will be inflated by security scanners pre-fetching pixels and links. If you're making decisions off a homegrown open rate, read why cold email open rates are lying to you before you optimize against the wrong metric.

7. Auth and the 3 a.m. failure mode

Microsoft retired basic authentication for SMTP AUTH on most tenants, so Microsoft 365 mailboxes need OAuth. Google OAuth refresh tokens expire after seven days while your app is in "Testing" publishing status — a classic DIY trap where everything works all week and dies on Monday. App passwords require 2FA and get revoked when security settings change. Token refresh, re-consent flows, and credential storage for a dozen mailboxes is real work, and it fails at inconvenient times.

The honest time math

Rough estimate from people who've done it: 20–40 hours to build something that handles sending, scheduling, bounces, reply detection, suppression, and multi-mailbox rotation properly. Then 2–5 hours a month on maintenance — provider API changes, token expiries, edge cases in bounce formats, adding a feature you didn't think you needed.

Value your time at even $50/hour and that's $1,000–$2,000 up front plus $100–$250 a month in ongoing cost, versus $0–$99 for software. The script wins only if you enjoy the building, or if your requirements are genuinely weird enough that no platform fits. We went deeper on this trade-off in build your own cold email sender or buy software.

When the script is still the right call

  • You're sending fewer than ~200 emails a month from one established mailbox and reading every reply personally.
  • Your personalization requires live data from internal systems that no platform can reach.
  • You're building outbound into a product, not running campaigns, and the sender is a component you'll maintain anyway.
  • You have a compliance constraint that prohibits third-party systems touching prospect data.

The hybrid most people end up with

The split that works: keep your code for the parts where it's genuinely better — scraping, enrichment, deduping, lead scoring, writing personalization variables — and push the finished list into a sending platform via CSV or API. You keep the custom logic and hand off throttling, warm-up, bounce handling, suppression, and reply threading to something that already solved them. Most teams that "built their own" and stuck with it are really doing this.

Where Sendvanta's free plan fits

The argument for scripting is usually a cost argument, and the cost argument gets weaker when the alternative is $0. Sendvanta's free plan is free forever with no credit card: 1,000 active leads, 3,000 emails per month, and up to 10 of your own SMTP mailboxes connected at a time. That covers multi-step sequences, warm-up inside your own workspace, deliverability health scoring with automatic slow-down, SpamAssassin scoring before send, bounce and suppression handling, one-click unsubscribe by default, and unified reply handling — the entire list above.

Honest caveats. The free tier connects your own SMTP/IMAP mailboxes; managed mailboxes ($4/mo each) and sending-domain registration (one-time $20) are paid add-ons, and free workspaces can be suspended after a month of inactivity. If you need more than 3,000 sends a month, Starter is $29/mo. And Sendvanta doesn't sell lead lists — you bring your own leads, which is exactly what you were doing with the script anyway. You can see the full feature list on /features, or compare the no-cost options in best free cold email software for small B2B teams.

Can I send cold email through SendGrid, Mailgun, or Amazon SES with a script?

Technically yes, practically no. Those are transactional/marketing ESPs whose acceptable use policies prohibit unsolicited commercial email, and they share IP pools. You'll get the account terminated, and in the meantime your messages inherit the reputation of everyone else on that IP. Cold email should go through your own Google Workspace, Microsoft 365, or SMTP mailboxes.

How many emails a day can I safely send from a Python script?

The same as from any tool: roughly 30–50 per mailbox per day on a warmed account, ramping up over several weeks. The script doesn't change the mailbox limits — provider reputation systems care about the sending mailbox and domain, not the client software.

Is warm-up something I can build myself?

Not realistically. Warm-up needs a pool of cooperating mailboxes exchanging real, labeled, replied-to messages. Running that yourself means buying and maintaining dozens of mailboxes that exist only to talk to each other — more expensive than any plan, and easy to do in a pattern that providers flag.

What's the single biggest thing scripts get wrong?

Suppression. One global list that's checked before every send, across every campaign and mailbox, including replies, bounces, and opt-outs. Teams usually implement it per-campaign, then email someone who already said no — which produces spam complaints, the most damaging signal to your domain reputation.

If I already built a script, is it worth throwing away?

Keep the enrichment and list-building code. That's the part with your IP in it. Hand the sending, warm-up, bounce handling, and reply management to a platform, free or paid, and feed it your finished lists.

Methodology: written on 18 February 2026, based on current Google Workspace and Microsoft 365 sending limits and authentication requirements, published acceptable-use policies for common transactional ESPs, and the operational failure modes most frequently reported by teams running self-built senders. Pricing reflects publicly listed plans at time of writing.

Ready to send outbound that lands?

Create your free Sendvanta workspace — no credit card required.

Start free