Author: onetwothreeadmin

  • GA4’s traffic attribution window: why conversions appear, then vanish

    GA4’s traffic attribution window: why conversions appear, then vanish

    You check Google Analytics 4 on Monday morning. Your email campaign drove twelve conversions over the weekend. You screenshot it, add it to your monthly report, feel good about the numbers.

    You check again on Friday. Those same conversions? Now it says nine.

    GA4 didn’t glitch. It’s working exactly as designed—and if you don’t understand why, you’re probably making decisions on data that’s still moving.

    How GA4’s attribution window actually works

    Google Analytics 4 uses a default attribution window of 90 days for most conversion events. That means when someone converts, GA4 looks back up to 90 days to find the traffic source that should get credit.

    But here’s the part that catches people: that window runs in both directions.

    If someone clicks your email link on May 1st, then converts on May 15th, GA4 assigns that conversion to email. Simple enough.

    But if someone clicks a Google ad on May 20th and converts on May 22nd, GA4 will reassign that conversion to paid search—even though it already showed up in your email report two weeks ago.

    The conversion doesn’t disappear from your total count. It just moves from one source to another. GA4 applies last-click attribution by default, so the most recent traffic source within that 90-day window wins.

    This is why your historical reports shift. Numbers you exported last week might not match what you see today, because conversions are still being reattributed as new sessions come in.

    What this means for your reporting

    If you’re tracking channel performance—especially for email, social, or content campaigns—you need to wait longer than you think before calling a campaign’s results final.

    A newsletter you sent two weeks ago might still be gaining or losing conversions as readers click other sources before they buy. If you report on it immediately, you’re only seeing part of the story.

    Here’s what changes:

    • Email campaigns look better early, worse later. People click your email, browse, then return via organic search or a retargeting ad. Email gets the early credit, but loses it when they convert through a different channel.
    • Paid ads look worse early, better later. Someone discovers you organically, clicks around, then converts after seeing a Facebook ad. The ad gets the conversion—even though organic did most of the work.
    • Organic and direct traffic gain conversions over time. These are the channels people use when they’re ready to buy. They’ll pick up conversions that were initially attributed to email, social, or referral traffic.

    If you’re exporting monthly reports, wait at least 7–10 days after the month ends before pulling final numbers. For high-consideration products or longer sales cycles, wait 30 days.

    How to change the attribution window (and when you should)

    You can adjust the conversion attribution window in GA4’s admin settings. Go to Admin → Data display → Attribution settings, then change the lookback window for acquisition and engagement.

    Your options are 30, 60, or 90 days.

    Shorten it to 30 days if:

    • You sell low-ticket digital products where people decide quickly
    • You run time-sensitive promotions and need faster, more stable reports
    • You want your reports to settle sooner, even if it means losing some cross-channel context

    Keep it at 90 days if:

    • You have a longer sales cycle (courses, coaching, SaaS with trials)
    • You want to see the full path people take before converting
    • You’re okay with reports shifting for a few weeks after a campaign ends

    There’s no universally correct answer. The right window depends on how long it typically takes someone to go from first visit to conversion in your business.

    How to work with this, not against it

    Stop treating GA4 reports as static. They’re not. Conversions move between sources as attribution updates, and that’s not a bug—it’s how the system is designed to give you a fuller picture over time.

    If you need stable, immediate numbers—say, for a weekly team check-in or a sponsor report—pull data from your payment processor or CRM instead. Stripe, Gumroad, and ConvertKit all give you transaction data that doesn’t shift retroactively.

    Use GA4 for what it’s actually good at: understanding patterns across traffic sources over weeks or months, not locking down exact counts two days after a campaign.

    And if you’re comparing performance across channels, compare them at the same point in their attribution lifecycle. Don’t judge an email campaign’s results after three days and a Facebook ad’s results after thirty. Wait the same amount of time for both, or you’re not comparing the same thing.

    Want more pieces like this? One Two Three Send breaks down the tools, tactics, and trade-offs that solo operators actually deal with. No fluff, no filler. Subscribe here.

  • Facebook Ads Library: how to spy on competitors (and when it’s useless)

    Facebook Ads Library: how to spy on competitors (and when it’s useless)

    Meta’s Ads Library is the only place where you can see every active ad running on Facebook, Instagram, Messenger, and Audience Network. It’s free, public, and updated in real time. If you run paid social campaigns—or you’re thinking about starting—it’s the most underused competitive intelligence tool you’re not using.

    Here’s how to use it correctly, what it can’t tell you, and where it saves you real money.

    What the Ads Library actually shows

    Go to facebook.com/ads/library, pick a country, and search for any Page name or keyword. You’ll see every ad that Page is currently running, plus:

    • Creative variations (images, video, carousel)
    • Ad copy and headlines
    • Call-to-action button text
    • First published date (when the ad went live)
    • Platforms and placements (Facebook Feed, Instagram Stories, etc.)

    You won’t see targeting, budget, performance metrics, or cost per result. Meta stripped that data after 2019. What you do get is the creative layer—the part most operators struggle with most.

    Three ways to use it before you spend a dollar

    Audit offer positioning. Search for competitors in your niche. Look at the ads that have been running longest—anything live for 60+ days is probably profitable or at least breaking even. What’s the core promise in the headline? What’s the first sentence of body copy? You’re not copying; you’re cataloging what’s survived budget scrutiny.

    I did this before launching a course in early 2025. I searched five adjacent creators. Four were leading with urgency (limited spots, closes Friday). One led with a specific outcome metric. That ad had been running for eleven weeks. I tested the outcome-first framing. It outperformed my urgency control by 28% on cost per landing page view.

    Map format trends by placement. Filter by platform. If you’re betting on Reels or Stories, see what successful advertisers in your category are actually running there. In Q1 2026, I saw a clear shift: operators selling info products moved from static carousels to lo-fi talking-head video with captions. The Ads Library showed the pattern two months before I saw think pieces about it.

    Reverse-engineer funnel shape. Look at the landing page URL in each ad (you have to click through). If a brand is running ten creatives and they all point to the same low-ticket offer page, that’s a direct-response play. If half go to blog posts and half to a lead magnet, that’s a nurture funnel. You’re seeing their acquisition strategy without a sales call.

    Where it’s useless (and costs you time)

    The Library won’t tell you if an ad is working. An ad running for six months might be break-even vanity spend, especially if it’s from a VC-backed brand. Longevity is a signal, not proof.

    It won’t show you who sees the ad. You can’t reverse-engineer audience targeting. If a competitor is profitable at $40 CPMs because they’re hitting warm traffic from a giant email list, you won’t know that. You’ll just see the creative and assume it works cold.

    And it’s terrible for local or B2B campaigns. If you’re selling SaaS to procurement managers or running ads for a three-location HVAC company, the sample size in the Library is too small. You’ll see one or two ads and draw the wrong conclusions.

    One workflow that saves money

    Before you brief a designer or write ad copy, spend 20 minutes in the Library. Search three competitors and one adjacent niche (same audience, different offer). Screenshot five ads. Note the format, headline structure, and CTA. Don’t copy. Use it as a creative brief.

    Then test your own angle against the pattern you found. If everyone’s using carousels, try video. If everyone leads with a question, lead with a number. The Library shows you the table stakes. Your job is to find the edge that isn’t there yet.

    If you’re running paid social and you’ve never opened the Ads Library, you’re guessing in a game where your competitors aren’t. It won’t replace testing, but it’ll cut your learning cost in half.

    Want to see how other operators are using paid and organic social together? Reply and tell me what you’re struggling with. I’ll cover it in a future edition.

  • Loom’s async video workflow vs. live Zoom calls: when to record

    Loom’s async video workflow vs. live Zoom calls: when to record

    Most solo operators treat video communication as binary: either you schedule a Zoom call or you send a text message. But there’s a third option that’s quietly become infrastructure for small teams and consultants — async video tools like Loom.

    The question isn’t whether async video is useful. It’s when it replaces a live call without losing clarity, and when it just creates more work.

    When async video actually saves time

    Loom works best when the communication is one-directional with optional follow-up. That means:

    • Product walkthroughs or onboarding. If you’re showing a client how to use your system, a 4-minute Loom beats a 30-minute call. They can pause, rewatch, and ask clarifying questions async.
    • Feedback on creative work. Instead of writing “the CTA button needs more contrast,” you record your screen, talk through the issue, and show exactly what you mean. The recipient doesn’t need to be there.
    • Status updates or reporting. If you’re walking through analytics, project progress, or a content calendar, async video delivers context without requiring everyone to block 30 minutes.
    • Bug reports or technical issues. Showing what’s broken — cursor movements, console errors, page behaviour — is faster and clearer than writing it out.

    The pattern: you’re delivering information, not negotiating or brainstorming. The recipient needs to understand, not co-create.

    When live calls still win

    Async video breaks down when the conversation is two-way, ambiguous, or high-stakes.

    • Sales calls or discovery. You can’t read body language or adjust your pitch in real-time via Loom. Async video works for demos after a discovery call, not instead of one.
    • Conflict resolution or difficult feedback. Tone is hard to control in async video. If the message could be misread as critical or defensive, do it live.
    • Strategy or brainstorming. If the goal is to iterate on ideas together, async video adds latency without adding clarity. A 15-minute Zoom call beats three rounds of recorded back-and-forth.
    • Complex negotiations. Pricing discussions, contract terms, partnership structure — these need real-time give-and-take.

    The test: if the other person will need to ask three follow-up questions, just schedule the call.

    The hidden cost of async video

    Loom’s free plan caps videos at 5 minutes; the paid tier (Loom Business at $12.50/user/month when billed annually) removes the limit. But the real cost isn’t the subscription — it’s response latency and context-switching.

    When you send a 6-minute Loom, you’re asking the recipient to:

    1. Notice the notification
    2. Find 6 uninterrupted minutes
    3. Watch at 1x or 1.5x speed
    4. Decide whether to reply async or schedule a follow-up

    If they’re juggling client work or deep focus time, that Loom might sit unwatched for 48 hours. Compare that to a text message (skimmable in 15 seconds) or a scheduled call (pre-committed time).

    Async video works when the recipient has slack in their schedule. If they’re underwater, it becomes a new tab they feel guilty about.

    Loom vs. Zoom: the operator’s rubric

    Here’s the decision tree:

    Use Loom when:

    • You’re explaining something visual (UI, design, analytics dashboard)
    • The recipient doesn’t need to respond immediately
    • You’d otherwise write 8+ paragraphs with screenshots
    • You’re delivering information, not seeking consensus

    Use Zoom (or a phone call) when:

    • The topic is ambiguous or exploratory
    • You need to read tone or body language
    • The conversation will have multiple back-and-forth turns
    • The stakes are high (sales, conflict, contracts)

    Use neither — just text — when:

    • The message is under 3 sentences
    • It’s purely informational (link, date, yes/no)
    • You don’t need tone or visual context

    One non-obvious Loom tip

    Enable emoji reactions in your Loom settings (under Preferences > Video Settings). Viewers can drop a thumbs-up or checkmark at specific timestamps without needing to reply. For simple feedback loops — “Does this make sense?” or “Approve this approach?” — it’s faster than waiting for a written response.

    Also: enable auto-transcription (it’s on by default in paid plans). Recipients can skim the transcript before deciding whether to watch. That alone cuts response time in half for some people.

    Async video isn’t a Zoom replacement. It’s a text-message replacement for things that need a screen. Use it when you’d otherwise write a novel with screenshots. Skip it when the conversation needs to breathe.

    Want more workflow breakdowns like this? Subscribe to One Two Three Send — we compare tools, tactics, and trade-offs for operators running online businesses. No fluff, no listicles, just the decision-making rubric.

  • Perplexity Pro vs. ChatGPT Plus: which research assistant to pay for

    Perplexity Pro vs. ChatGPT Plus: which research assistant to pay for

    If you’re running a content business solo, you’re already paying for at least one AI subscription. The question isn’t whether these tools are worth it—it’s which one deserves the $20/month when you can only justify one line item.

    ChatGPT Plus and Perplexity Pro both pitch themselves as research assistants. Both cost $20/month. Both let you ask questions and get answers with citations. But after three months of using both daily for newsletter research, SEO competitor analysis, and product development, the differences are sharper than the marketing suggests.

    What you’re actually paying for

    ChatGPT Plus gets you access to GPT-4 and GPT-4o, faster response times, priority access during peak hours, and the ability to use custom GPTs and browse the web. The browsing feature is important here—it’s what lets ChatGPT search the internet and cite sources, but it’s not the default behavior. You need to explicitly tell it to search, or use a GPT configured to do so.

    Perplexity Pro gives you unlimited access to its Pro Search mode, which uses GPT-4, Claude 3.5 Sonnet, or other frontier models depending on your choice. Every query automatically searches the web and returns cited answers. You also get file upload, API access, and the ability to choose which model runs each search. The free tier limits you to five Pro searches per day.

    The core difference: ChatGPT is a reasoning engine with optional search. Perplexity is a search engine with advanced reasoning. That distinction matters more than the feature lists suggest.

    When Perplexity wins

    Use Perplexity when you need quick, cited answers to fact-based questions. It excels at surface-level research where you need to verify a claim, find recent statistics, or compare a handful of sources quickly.

    I use it for:

    • Checking pricing or feature changes across SaaS tools when writing comparisons
    • Finding recent case studies or public metrics (“show me examples of newsletters that grew using referral programs in 2025”)
    • Validating technical claims before I publish (“what’s the current recommendation for WordPress PHP memory limits”)
    • Quick competitive research when a reader asks about a tool I haven’t used

    Perplexity’s interface is built for speed. One search box, one answer, sources below. No conversation history cluttering the UI unless you want it. When I need a fast fact-check mid-draft, I’m in and out in under a minute.

    The model-switching is useful but overhyped. I default to Claude 3.5 Sonnet for most queries because it writes more naturally, but the difference in search quality is marginal. GPT-4 and Sonnet pull from the same web index.

    When ChatGPT wins

    Use ChatGPT when you need deep reasoning, multi-turn collaboration, or task-specific workflows that don’t require real-time data.

    I use it for:

    • Drafting and editing. Canvas mode is legitimately good for iterating on article structures or rewriting clunky intros.
    • Building repeatable prompts or workflows. Custom GPTs let me save instructions for recurring tasks (“rewrite this in operator-to-operator voice” or “extract key takeaways from this transcript”).
    • Complex analysis where I’m uploading CSVs, PDFs, or screenshots and need synthesis, not just citation.
    • Brainstorming or expanding rough ideas into outlines. Perplexity gives you an answer; ChatGPT helps you think through the question.

    ChatGPT’s browsing is slower and less reliable than Perplexity’s search, but when it works, it’s more contextually aware. If I ask it to “find three examples of SaaS companies using tiered pricing with a free tier and compare their upgrade triggers,” it’ll structure the response more coherently than Perplexity, even if it takes longer to load.

    The custom GPTs are where Plus justifies itself for solo operators. I have one configured to analyze newsletter performance data, another to reformat raw interview notes into publishable Q&A format, and a third that helps me write product comparison tables. These aren’t magic—they’re just saved prompts with file upload—but they eliminate the friction of re-explaining the same task every time.

    The honest ROI calculation

    If you write daily and need research speed more than reasoning depth, Perplexity Pro is the better $20. If you’re editing, outlining, or working with uploaded documents more than you’re chasing citations, ChatGPT Plus wins.

    I pay for both because the overlap is smaller than it looks. Perplexity replaced my habit of opening ten tabs and skimming blog posts. ChatGPT replaced my habit of staring at a blank Google Doc waiting for an outline to emerge.

    But if I could only keep one? I’d keep ChatGPT Plus and use free Perplexity for the five queries per day that need citations. The reasoning and iteration are harder to replace than the search.

    One last thing: neither tool is a substitute for primary research. They summarise what’s already published. If you’re writing anything that requires original data, interviews, or firsthand testing, you still need to do that work yourself. These tools make you faster—they don’t make you more original.

    What’s your experience? If you’re paying for one of these, reply and tell me which tasks justified the subscription. I’m curious whether the use cases are clustering or if solo operators are using these in completely different ways.

    Heads up — some links in this article are affiliate links. If you sign up through them, we may earn a small commission at no extra cost to you. We only recommend tools we use ourselves.

  • WordPress Heartbeat API: what it costs you and how to tame it

    WordPress Heartbeat API: what it costs you and how to tame it

    If you’ve ever watched your WordPress hosting dashboard and wondered why your server CPU spikes every few seconds even when nobody’s actively editing a post, you’re looking at the Heartbeat API in action.

    The Heartbeat API is a core WordPress feature that creates a persistent connection between your browser and the server. It’s what lets you see “User X is currently editing this post” warnings, autosaves your draft every 15 seconds, and keeps your session alive when you leave a tab open for hours.

    It’s useful. It’s also chatty. And for solo operators running lean hosting setups, that chattiness has a real cost.

    What the Heartbeat API actually does

    Every 15 seconds by default, the Heartbeat API sends a request from your browser to your WordPress server. The server responds with any updates: post lock status, comment counts, plugin notifications, whatever’s changed since the last ping.

    That 15-second interval runs constantly while you have the WordPress admin open. If you’re editing a post, it’s checking for conflicts. If you’re on the dashboard, it’s refreshing widget data. If you have three tabs open and forgot about two of them, all three are pinging your server every 15 seconds.

    On a VPS with 2GB of RAM and a handful of plugins, this usually isn’t catastrophic. But it’s not free, either. Each heartbeat request consumes a PHP worker thread. If you’re running a lean hosting setup—shared hosting, a small cloud instance, or a server that’s already near capacity during traffic spikes—those threads add up.

    I’ve seen operators blame their cache plugin or their theme when the real culprit was eight browser tabs hammering the Heartbeat API while they edited a landing page.

    When to throttle it

    You don’t need to kill the Heartbeat API entirely. You just need to decide where the tradeoff between real-time updates and server load makes sense for your workflow.

    Throttle on the front end. The Heartbeat API can run on public-facing pages if a plugin or theme calls it. Most solo operators don’t need this at all. Disable it entirely for logged-out visitors.

    Slow it down in the admin. If you’re not collaborating in real time with another editor, you don’t need 15-second intervals. Stretching it to 60 seconds in the WordPress admin still gives you autosave protection and session continuity without the constant polling.

    Keep it active in the post editor. If you write long-form content or frequently step away mid-draft, autosave is worth the overhead. A 30-second interval here is a reasonable compromise.

    How to control it without a plugin

    The cleanest way to manage Heartbeat is with a small snippet in your theme’s functions.php or a custom plugin. Here’s what I use:

    add_action('init', 'custom_heartbeat_settings');
    function custom_heartbeat_settings() {
      // Disable on front end
      if (!is_admin()) {
        wp_deregister_script('heartbeat');
      }
    }

    add_filter('heartbeat_settings', 'adjust_heartbeat_interval');
    function adjust_heartbeat_interval($settings) {
      // Slow to 60 seconds in admin, 30 in post editor
      $settings['interval'] = is_admin() ? 60 : 30;
      return $settings;
    }

    This disables Heartbeat for all logged-out users, slows the admin dashboard polling to once per minute, and keeps the post editor at 30 seconds. Adjust the numbers based on your workflow.

    If you’d rather use a plugin, Heartbeat Control (free, in the WordPress repo) gives you a settings panel with the same options. It’s lightweight and doesn’t add cruft.

    What you’ll actually notice

    Throttling Heartbeat won’t magically make your site twice as fast. It’s a marginal win, not a transformation. But marginal wins compound, especially on shared hosting or small VPS plans where every bit of overhead matters.

    What you will notice: fewer unexplained PHP worker exhaustion errors during traffic spikes, slightly lower baseline CPU usage, and fewer “server busy” messages when you’re editing posts while a newsletter sends.

    If you’re running WordPress on a tight resource budget—single-core VPS, entry-level managed hosting, or a shared plan you haven’t outgrown yet—Heartbeat throttling is one of the first optimizations worth making. It costs you almost nothing in workflow convenience and buys back real server capacity when you need it.

    Got a hosting or performance question? Reply to this email or share what’s slowing your site down. We’ll cover it in a future issue.

  • How to set up Amazon SES for sending your newsletter — a complete step-by-step guide

    How to set up Amazon SES for sending your newsletter — a complete step-by-step guide

    Amazon SES (Simple Email Service) is the cheapest reliable way to send a newsletter at scale. Ten cents per thousand emails. No subscription, no per-contact pricing. Big publishers run their entire mailing on it — Substack, Beehiiv, Mailchimp, Resend, Postmark — all of them sit on top of SES or similar AWS infrastructure underneath.

    The trade-off: you set it up yourself. AWS doesn’t hand-hold. This guide walks every step end-to-end so you don’t get stuck on the parts that catch most operators (DNS records, sandbox approval, bounce handling). Plan on 30–45 minutes the first time you do this.

    Before you start

    • A domain you own (e.g. yourname.com). You’ll send from [email protected] or similar. SES verifies the entire domain, not individual email addresses, so this is the right approach for a newsletter.
    • Access to your domain’s DNS — wherever you registered the domain (Namecheap, GoDaddy, Cloudflare, Route 53). You’ll add 4–5 records.
    • An AWS account. Free to create. AWS asks for a credit card but you won’t be charged unless you send mail.
    • 10 minutes patience for DNS propagation between steps.

    Step 1 — Sign in to AWS and open SES

    Go to aws.amazon.com/console and sign in (or create an account — pick “Personal” or “Business”, give them a card, you’re done).

    Once you’re in the AWS Console, type “SES” in the top search bar and click Amazon Simple Email Service. You’ll land on the SES home page.

    Step 2 — Pick your region

    This matters. SES is region-scoped — settings you make in one region don’t exist in another. Top right of the console there’s a region picker (it’ll say something like “N. Virginia” or “Oregon”).

    Pick the region closest to most of your subscribers. For a US audience: us-east-1 (N. Virginia) or us-west-2 (Oregon). For Europe: eu-west-1 (Ireland) or eu-central-1 (Frankfurt). The region affects deliverability latency but only marginally. Pick one and stick with it — moving later means re-verifying your domain.

    Step 3 — Verify your sending domain

    In the left sidebar of SES, click Verified identities, then Create identity.

    • Identity type: Domain (not Email address — domain verification covers every address on the domain).
    • Domain: enter your domain (e.g. yourname.com, no www, no https://).
    • Tick Use a custom MAIL FROM domain and enter a subdomain like mail.yourname.com. This is what shows up in bounce-handling headers — using your own MAIL FROM domain dramatically improves deliverability.
    • Under Advanced DKIM settings: leave Easy DKIM selected, RSA_2048_BIT. Tick Publish DNS records to Route 53 only if your DNS lives in Route 53; otherwise leave unticked.
    • Click Create identity.

    SES gives you a screen with DNS records to add. Keep this tab open — you’ll need it in the next step.

    Step 4 — Add the DNS records

    You’ll add four sets of DNS records. Log into your DNS host (Namecheap, GoDaddy, Cloudflare, etc.) in a separate tab.

    4a — DKIM records (3 CNAMEs). SES gives you three CNAME records that look like abc123._domainkey.yourname.com pointing at abc123.dkim.amazonses.com. Add all three exactly as shown. These prove emails you send are actually from you.

    4b — MAIL FROM records (2 records). One MX record on the subdomain you chose (mail.yourname.com) pointing at feedback-smtp.[region].amazonses.com with priority 10, and one TXT record on the same subdomain with value "v=spf1 include:amazonses.com ~all".

    4c — SPF on the root domain. Add (or update) a TXT record on yourname.com with value "v=spf1 include:amazonses.com ~all". If you already have an SPF record, don’t add a second one — edit the existing one to include include:amazonses.com before the closing ~all.

    4d — DMARC. This isn’t required by SES but Gmail and Yahoo now require it for bulk senders (5,000+/day). Add a TXT record on _dmarc.yourname.com with value "v=DMARC1; p=quarantine; rua=mailto:[email protected]; pct=100; adkim=s; aspf=r;". Replace the email address with one you check.

    Wait 5–10 minutes, then back in the SES tab refresh the Verified identities page. The domain should flip to Verified with DKIM Successful. If it doesn’t after 30 minutes, your DNS records are wrong — open them in your DNS host and compare character-by-character to what SES shows.

    Step 5 — Request production access (leave the sandbox)

    By default, every new SES account is in sandbox mode: 200 emails per day, and you can only send to verified email addresses. That’s useless for a newsletter.

    In the SES console sidebar, click Account dashboard. You’ll see a banner saying you’re in the sandbox. Click Request production access (or Get set up).

    The form asks why you want to send mail. Answer honestly and specifically — vague applications get rejected. Good template:

    Mail type: Marketing

    Website URL: https://yourname.com

    Use case description: “I run a newsletter at yourname.com. Subscribers sign up via a double-opt-in form on the website and confirm via a verification email. They receive a weekly newsletter on [your topic]. Unsubscribes are honoured immediately via one-click unsubscribe headers (RFC 8058) and a footer link. I will monitor bounces and complaints via SNS topics and remove problem addresses automatically. Expected initial volume: 1,000 emails/day, growing with the list.”

    Additional contacts: “I do not buy email lists. All addresses come from people who actively signed up on my website.”

    Submit. AWS typically approves within 24 hours, often within 2–4 hours. If they reject (usually for vague applications), reply with more specifics — they’ll re-review.

    Step 6 — Create SMTP credentials

    While you wait for production approval, set up the credentials your newsletter plugin will use to send.

    In the SES sidebar, click SMTP settings. You’ll see the SMTP endpoint for your region (e.g. email-smtp.us-east-1.amazonaws.com) and a port (use 587 with STARTTLS).

    Click Create SMTP credentials. AWS creates an IAM user behind the scenes that has permission to send mail through SES. Copy the SMTP username and password immediately — AWS shows them once and never again. Save them in a password manager.

    Step 7 — Set up bounce and complaint handling (SNS)

    This step is optional but strongly recommended. SES will email you about bounces and complaints by default, but for a real newsletter you want them processed automatically — bounces auto-removed from your list, complaints flagged for review.

    In the AWS Console, search SNS and open Simple Notification Service. Create two topics — one called ses-bounces, one called ses-complaints. Note the ARN (Amazon Resource Name) of each.

    Back in SES, open your verified domain identity, scroll to Notifications, and assign the SNS topics to Bounce and Complaint feedback. Save.

    Now you can subscribe an HTTPS endpoint (your WordPress site) to those topics to auto-process events. Most decent newsletter plugins have a webhook endpoint for this. If yours doesn’t, leave the SNS topics in place and check them manually weekly — better than nothing.

    Step 8 — Configure your newsletter plugin

    Open your newsletter plugin’s settings (in WordPress: Newsletter → Settings → Sender or Email Provider). Pick SMTP as the provider type and enter:

    • Host: email-smtp.[your-region].amazonaws.com
    • Port: 587
    • Encryption: TLS (also called STARTTLS)
    • Username: the SMTP username from Step 6
    • Password: the SMTP password from Step 6
    • From email: any address on your verified domain (e.g. [email protected])
    • From name: your newsletter’s name

    Save the settings.

    Step 9 — Send a test

    From the newsletter plugin, send a test email to your own address. If it arrives, you’re done. If it doesn’t:

    • Check the plugin’s send log for the error message.
    • If you see “535 Authentication failed”: SMTP credentials are wrong. Re-create in SES (Step 6) and re-paste.
    • If you see “Email address not verified”: you’re still in sandbox mode. Either wait for production approval, or verify your test recipient address in SES → Verified identities first.
    • If you see “Daily sending quota exceeded”: you’ve hit the 200/day sandbox limit. Same fix — wait for production approval.

    What it costs

    SES pricing is straightforward: $0.10 per 1,000 emails sent. That’s it. A 10,000-subscriber newsletter sending one weekly issue costs $4/month. Compare to ConvertKit at $79/month for the same list, or Mailchimp at $100+. For pure deliverability infrastructure, nothing beats SES on price.

    If you’re hosting your WordPress site on EC2, you also get 62,000 emails/month free from SES — only when sent from an EC2 instance. Most operators won’t hit this.

    Common gotchas

    Sandbox limits are real. Don’t announce your launch before production access is approved. Apply the day you set SES up.

    DNS propagation is slow. If your records look right but the domain won’t verify, give it 30 minutes. Cloudflare propagates in 1–2 minutes; Namecheap can take 30+.

    Don’t reuse the same SPF record. If you have one already (most domains do), edit it to include amazonses.com — don’t add a second TXT record. Multiple SPF records on the same domain break email auth entirely.

    Watch your bounce rate. SES will throttle or suspend you if your bounce rate exceeds 5% or complaint rate exceeds 0.1%. Process bounces. Remove invalid addresses.

    Warm up the IP. If you’re going from 0 to 50,000 sends overnight, AWS will throttle you anyway. Ramp gradually over 2–4 weeks if possible.

    Once you’re up

    That’s the whole setup. From here on, SES is the cheapest, most reliable workhorse in your stack — your newsletter plugin handles the editorial workflow, SES handles the sending, AWS bills you ten cents per thousand emails sent.

    If you’re running One Two Three Send on WordPress, the SMTP provider option above is built in — paste the SES credentials into Newsletter → Settings → Email Provider and you’re sending. Same plugin, same workflow, infrastructure that costs $4/month instead of $100.

    Subscribe to One Two Three Send for more no-nonsense guides on the infrastructure behind running a profitable newsletter.

    Some links in this post are affiliate links — we earn a small commission if you sign up through them, at no cost to you. We only recommend tools we actually use.

  • Beehiiv’s referral program: how it works and when it backfires

    Beehiiv’s referral program: how it works and when it backfires

    Beehiiv‘s referral program is one of its flagship features—a built-in system that lets subscribers unlock rewards by forwarding your newsletter. It’s fast to set up, requires no integrations, and can drive genuine word-of-mouth growth.

    It can also quietly ruin your list quality if you don’t understand how it actually works.

    Here’s the mechanical breakdown, the non-obvious tradeoffs, and when to disable it entirely.

    How the referral system actually works

    When you enable the referral program in Beehiiv, every subscriber gets a unique referral link. That link appears automatically in your newsletter footer (or wherever you embed the merge tag). When someone signs up through that link, the original subscriber earns credit toward rewards you define—free downloads, paid tier access, physical products, whatever.

    Beehiiv tracks this server-side. No third-party pixels, no JavaScript. The platform knows who referred whom, even if the new subscriber uses a different device or email client.

    You configure reward milestones in the dashboard: 3 referrals unlocks a PDF, 10 gets a paid subscription comp, 25 gets a shirt. Beehiiv handles the tracking and sends automated emails when someone hits a tier. You fulfill the reward manually (or auto-comp paid subscriptions if you’re using Beehiiv’s native monetization).

    The feature is available on the Scale plan and above—$99/month if you’re under 10,000 subscribers, more as you grow. The Grow plan ($49/month) doesn’t include it.

    Where it works well

    Referral programs succeed when your content has shareability baked in—either because it solves urgent, specific problems (“how to fix X”) or because sharing it signals identity (“I’m the kind of person who reads this”).

    If your newsletter is tactical—SEO breakdowns, monetization teardowns, tool comparisons—referrals tend to flow naturally. Readers share because the content is immediately useful to peers in the same situation.

    If your newsletter is aspirational or community-driven—indie hacker diaries, niche hobby deep-dives—referrals work because sharing is a form of curation. “You should read this” becomes “you should be in this club.”

    The mechanic also works if your baseline engagement is already strong. If 30–40% of your list opens consistently and 5–8% click, a referral program amplifies what’s working. If your open rate is 18% and falling, referrals won’t save you—they’ll just add more cold contacts.

    Where it backfires

    The biggest risk: misaligned incentives. If your rewards are valuable enough to motivate sharing, they’re also valuable enough to motivate gaming. Subscribers will invite people who don’t care about your content—they care about the reward.

    I’ve seen lists add 400 subscribers in a week via referrals, only to watch open rates drop from 42% to 28% because half the new signups never intended to read. They clicked a friend’s link to help them hit a milestone, then ignored every send.

    Beehiiv doesn’t penalize you for this directly, but your email provider’s reputation system does. If new subscribers consistently don’t open, Gmail and Outlook start filtering you to spam—even for engaged readers.

    The second issue: reward fulfillment overhead. If you’re offering anything other than automated digital perks, you’re adding manual work every time someone hits a tier. Sending books, comping Stripe subscriptions, or giving one-on-one access doesn’t scale quietly. At 50 referrals a week, it’s a part-time job.

    Third: the program becomes the content. Once you launch referrals, a chunk of every send has to remind people the program exists, explain how it works, and show the leaderboard. That’s 80–150 words per issue that aren’t about your core topic. Some readers tune it out. Others resent the hustle.

    The non-obvious tip: test with time limits first

    Instead of launching a permanent referral program, run it as a 30-day sprint. Announce it, track it, fulfill rewards, then turn it off and watch what happens to your engagement metrics over the next month.

    If open rates stay flat or improve, and new subscribers engage at the same rate as your baseline, the program worked. If engagement drops or you see a spike in unsubscribes from recent signups, you attracted the wrong people.

    Beehiiv makes it easy to pause the program without losing historical referral data—just toggle it off in settings. The links stop working, the leaderboard disappears from your emails, and you can reactivate later if the economics make sense.

    One more thing: if you do run referrals, set a cap on reward tiers. I’ve seen operators offer “lifetime free access” at 100 referrals, then realize someone hit it by spamming Reddit. Build an upper limit—maybe 50 referrals max—so your highest reward doesn’t become a liability.

    Want to see how other operators are thinking about growth mechanics? Reply with what you’re testing—I read every response and the good ones become future pieces.

    Heads up — some links in this article are affiliate links. If you sign up through them, we may earn a small commission at no extra cost to you. We only recommend tools we use ourselves.

  • Monetising a product is easier than monetising attention

    Monetising a product is easier than monetising attention

    Most online operators start with the attention model: build an audience, then figure out how to extract money from their time. Newsletter sponsorships. Display ads. Affiliate links tucked into content. It feels like the natural path because it’s what you see working for others.

    But there’s a reason why operators who switch to product revenue—courses, memberships, software, templates, anything with a defined deliverable—rarely switch back. Product models scale differently, and for solo operators especially, they scale better.

    The attention tax compounds quietly

    When you monetise attention, every dollar requires continuous performance. A sponsorship pays once, then expires. Ad revenue tracks your traffic month to month. Affiliate income depends on someone else’s conversion funnel and commission structure.

    You’re not building equity. You’re renting out capacity.

    The math gets worse as you grow. To double sponsorship revenue, you need to double your audience or double your rate. Rates have ceilings—sponsors comparison-shop, and CPM benchmarks are public. So you chase growth, which means more content, more consistency pressure, more surface area to maintain.

    Then there’s the editorial drift. A reader-funded model points you toward what readers value. An attention model points you toward what scales: volume, virality, topics that pull search traffic even if they’re not what you’d choose to write about. Over time, the publication bends toward the model.

    Products let you decouple revenue from output

    Selling a product means you can earn the same amount while publishing less. A course that brings in $3,000 a month doesn’t care whether you published twice this week or not at all. A membership that delivers one deep tutorial every two weeks scales your income without scaling your content treadmill.

    This isn’t about working less—it’s about where you point your working hours. Instead of optimising for volume (another post, another sponsor, another traffic play), you optimise for conversion and retention. You spend time on the product, the onboarding flow, the member experience, the case studies that close sales.

    Products also let you serve smaller audiences profitably. A newsletter with 2,000 subscribers is almost impossible to monetise via sponsorships—your inventory is too small, your rates are too low, and sponsors want five-figure lists. But 2,000 subscribers with a $99 course and a 2% conversion rate is $4,000 in revenue from a single launch. Run that twice a year while growing the list, and you’ve got a real business.

    The chief objection: “I don’t have a product idea”

    This is almost never the real problem. If you’re writing regularly about a topic, you’re already teaching. The product is just the teaching formatted differently—less frequent, more structured, with a defined outcome.

    Start with what people already ask you to explain twice. That’s the course. Start with what you’d build for yourself if you had four hours. That’s the template or tool. Start with the workflow you’ve refined over two years that newcomers are still guessing at. That’s the membership.

    The other common block: “I don’t want to do a big launch.” Fine—don’t. Sell evergreen. Put a product page in your site footer. Mention it once per month in your newsletter. Let it convert passively while you write. You’ll be surprised how many people buy something useful without a countdown timer.

    Attention models aren’t wrong—they’re just expensive

    Sponsorships and ads work. They work especially well if you’re already at scale, if you have a team handling sales and production, or if your content velocity is naturally high and you’re not burning out.

    But for solo operators, the cost isn’t just time—it’s option value. Every hour spent chasing another sponsorship is an hour you didn’t spend building something that compounds. Every editorial decision bent toward traffic is a decision away from the tight, specific thing your best readers would pay for.

    If you’re still early, or if you’re hitting the ceiling on attention-based models and wondering what’s next, the move isn’t to optimize your sponsor deck. It’s to spend a month building the thing you’d sell if someone asked you to solve their problem directly.

    Then sell that.

    What’s one product you could ship in the next 30 days using what you already know? Reply and tell me—I read every response, and I’ll send you the follow-up guide on evergreen product funnels for solo operators.

  • When to add Beehiiv on top of your WordPress newsletter (and when not to)

    When to add Beehiiv on top of your WordPress newsletter (and when not to)

    If you already run a newsletter on WordPress, the most common question you’ll see in the operator forums isn’t “should I switch to Beehiiv — it’s “should I also be on Beehiiv?”. The framing matters, because Beehiiv stops looking like a competitor to a WordPress setup the moment you treat it as an acquisition channel rather than a publishing platform.

    We’ve been running both for the last several months. Here’s the honest decision framework we wish someone had handed us before we set the second one up.

    What Beehiiv actually adds (that WordPress can’t replicate)

    If you’re on WordPress, you already have the things that matter most — ownership of your subscriber list, deliverability control, your own domain, SEO that compounds on your archive, and pluggable customisation. None of those reasons go away when you add Beehiiv. So what does Beehiiv bring?

    The recommendations network. This is the single thing worth crossing the bridge for. Beehiiv’s discovery engine — both the in-post widget that suggests other newsletters to your readers, and the dedicated discovery network that surfaces your newsletter to people reading something adjacent — is the cheapest first-1,000-subscribers channel that currently exists. No WordPress plugin replicates it, including the cross-promotion plugins (we know — we’ve built one). The reason it works is network density, and you only get into that network by being on Beehiiv.

    Boosts. A pay-per-acquired-subscriber marketplace where you pay another newsletter operator to recommend you. The economics are deterministic in a way Meta and Google ads aren’t — you set a price per qualified sub, you only pay when one signs up. Boosts often outperform paid social on a CPA basis for newsletter-adjacent audiences.

    The ad network (optional revenue line). Beehiiv inserts sponsored ads into your posts and pays you a share. It’s not life-changing money at small list sizes, but it’s a real recurring revenue line with zero ongoing work — useful if you want monetisation without selling sponsorships yourself.

    That’s the value of adding Beehiiv. Now the cost.

    What it actually costs

    The plan tier you’ll end up on is somewhere in the Launch / Scale range — call it $0–$50/month depending on list size. That’s the obvious cost. The less obvious ones:

    • Time to keep two systems in sync. The bridge isn’t free. Every published issue needs to be cross-posted to Beehiiv if you want the web archive there to stay alive, and every signup on Beehiiv needs to find its way into your WordPress subscriber list (which is doable via their webhook system, but is one more thing to monitor).
    • Cognitive overhead. You’re now reading two analytics dashboards, debugging two send pipelines, and answering subscriber emails about which platform their account is on. For an individual operator this is real friction.
    • Audience confusion. If you mention your newsletter on social, which subscribe link do you give? If a reader asks “where can I read your archive?”, do you say the WordPress URL or the Beehiiv one? You’ll need a clear answer.
    • A small ongoing distraction. Beehiiv’s product is genuinely good, and once you’re inside it the upsell to use it as your primary platform (with their ad network, their paid tier infrastructure, their automation tools) is constant. Resist this if your WordPress side is working.

    When the addition is worth it

    The simple test: are you under 5,000 subscribers and actively trying to grow? Then yes, the recommendations network is probably the single highest-leverage thing you can add to your stack right now. The platform fee is negligible at that size, and the acquisition channel pays for itself within the first month if you’re publishing regularly.

    Two more specific cases where adding Beehiiv is a clear win:

    You publish about a topic that has natural cross-recommendation density on Beehiiv. Newsletter-about-newsletters, finance, sports, tech, lifestyle — these have hundreds of active publications on Beehiiv, which means the recommendations engine has something to work with. Hyper-niche B2B topics with three peer newsletters in the world won’t see much benefit.

    You want a passive revenue line that doesn’t require selling sponsorships. The Beehiiv ad network won’t replace your day job, but it’s real monthly money. For an operator who’d rather write than sell, it’s worth turning on.

    When the addition is wrong

    If your audience is past about 25,000 free subscribers or 2,500 paid, the platform fee starts to bite and the recommendations engine’s marginal value drops (your growth is mostly word-of-mouth and SEO at that scale anyway). Stick to your WordPress + Resend stack and put the saved fee toward content.

    If your newsletter is part of a larger product business — a course, an agency, an ebook funnel, a community — you don’t want subscriber records living in two places. The reconciliation overhead is more painful than the recommendations are valuable. Stay single-stack on WordPress.

    If you’ve been burnt by platform suspensions before, you have a real reason to be cautious. Beehiiv’s account-suspension issues are uncommon but documented — the difference vs WordPress is that on WordPress your worst case is a hosting bill, on Beehiiv it can be losing access to your audience without warning. The mitigation is to keep WordPress as the source of truth (which is what we do) so a Beehiiv suspension would cost you the discovery channel, not the list.

    How to set up the bridge cleanly

    If you decide to add Beehiiv, the configuration that gives you the most value with the least operational pain:

    1. Make WordPress the source of truth for subscribers. Every signup, wherever it lands, should end up in your WordPress subscriber table. Beehiiv’s API + webhooks let you wire this up — when someone signs up on Beehiiv, the webhook fires and creates the row on your side.
    2. Send the email from WordPress. You control deliverability, sender authentication, and per-issue customisation. Beehiiv’s send infrastructure is fine but you give up the levers.
    3. Use Beehiiv only as the acquisition layer and web archive. Recommendations engine on, Boosts marketplace on, ad network on if you want the revenue. But sending — the actual mail going out — runs through your WordPress stack.
    4. Cross-post each issue to Beehiiv as content. So the Beehiiv-side archive stays alive, the discovery network keeps surfacing your posts, and readers who arrive via Beehiiv have something to read. The Create Post API is on Beehiiv’s Enterprise tier today, so practically this means a copy-paste step into their editor or a manual import of the HTML.

    If you’re running One Two Three Send Pro on the WordPress side, the Beehiiv integration is built in — paste an API key and publication ID into Settings → Beehiiv, and the subscriber webhook + push side is wired up. The cross-post side is technically wired too, but it’ll only fire if you upgrade to Beehiiv Enterprise (their API restriction, not ours).

    The honest summary

    Adding Beehiiv to a WordPress newsletter is the right call for most operators between 0 and 5,000 subscribers who are actively trying to grow. It’s the wrong call once your acquisition is already working, or once your subscriber count is large enough that platform fees become meaningful.

    The pattern that works long-term is to treat the two platforms as different jobs — WordPress as your owned publishing layer, Beehiiv as a discovery channel that feeds it. That positioning protects you from the worst case on Beehiiv (account suspension, pricing changes) while still letting you use what’s genuinely best about it.

    If you’re starting from “I’m on WordPress, should I add Beehiiv too?” — the answer is probably yes, for now. Just be clear-eyed about which job each platform is doing for you, and don’t let the addition turn into a migration without you noticing.

    Some links in this post are affiliate links — we earn a small commission if you sign up through them, at no cost to you. We only recommend tools we actually use.

  • Everything that breaks the first time you take a Stripe payment for your newsletter

    Everything that breaks the first time you take a Stripe payment for your newsletter

    Stripe is the default payment processor for most online newsletter and creator businesses, and it’s worth understanding because most operators end up using it whether they planned to or not. Substack is built on Stripe. Beehiiv is built on Stripe. Kit, ConvertKit, Memberful, Lemon Squeezy — all Stripe. If you’ve ever sold a paid subscription, you’ve already met it, even if you didn’t see the dashboard.

    This post is for operators thinking about going beyond the platform — running their own paid tier on WordPress, selling a one-off product, or running a small agency that needs to invoice cleanly. We’ll cover what Stripe actually is, what it costs at newsletter scale, the four concepts that trip up most operators on first contact, the real pitfalls (activation, tax, chargebacks), and when not to use it.

    What Stripe is, in one paragraph

    Stripe is a payment infrastructure company that handles the messy middle between your website and the card networks (Visa, Mastercard, Amex). When a subscriber clicks “Subscribe $10/month” on your newsletter, Stripe collects the card, runs it through fraud checks, charges it via the bank, deals with international currency conversion, retries failed cards on a schedule, sends the customer a receipt, and shows up in your bank account a few business days later as a deposit. You never touch the card data. You never run a banking integration. You pay them roughly 2.9% + 30¢ per transaction and they handle the rest.

    What makes Stripe different from PayPal or Square is that it’s developer-first. The API is excellent, the dashboard is good (not great, but good), and it’s the one platform where every newsletter tool, course platform, and SaaS app can integrate easily. That ecosystem effect is the moat.

    What it actually costs at newsletter scale

    Stripe’s standard rate is 2.9% + 30¢ for US cards and 3.4% + 30¢ for international cards. Real averages for US-based newsletter operators end up around 2.9–3.4% all-in.

    Annual revenueStripe fees (approx)What that buys
    $10,000$300~440 charges processed, customer portal, dunning, receipts
    $50,000$1,500Same plus fraud detection on autopilot
    $250,000$7,500Volume discount eligibility (negotiable above $1M)

    For comparison, building anything close to this from scratch — fraud detection, retry logic, customer-facing portal, tax handling — costs more than the fees. The Stripe rate is the cheapest part of the whole stack. Operators who agonise over the 2.9% are usually missing what they’d spend rebuilding it.

    The four use cases for a newsletter operator

    1. Paid newsletter subscriptions

    The big one. Monthly and annual recurring subscriptions, typically $5–15/month or $50–150/year. Three patterns work for newsletters:

    • Monthly + annual + founding member. Standard Substack split. Annual gets a 17% discount. Founding member is 10x the annual price for readers who want to support the publication beyond the standard tier — surprisingly common at the right audience size.
    • Annual only. Eliminates the worst-converting tier (monthly), reduces churn, simplifies cashflow forecasting. Used by operators who want a smaller list of higher-LTV readers.
    • Pay what you want above a floor. Stripe supports this via Custom Pricing on Checkout. $5/month minimum, customer enters whatever they want above. Niche but works for community-driven newsletters.

    2. One-off products

    Ebooks, course access, sponsored slots, archive bundles. One-off charges with optional digital delivery via Stripe’s Payment Links (zero coding, drag-and-drop). For a newsletter operator selling a $29 ebook, Payment Links is the fastest route — generate a link, paste in your newsletter, done.

    3. Tipping / donations

    Some readers want to support a free newsletter without subscribing. Set up a Stripe-hosted Payment Link with custom amount enabled. One-line install in your footer: “Tip the writer →”. Closer to a Patreon model but without the platform tax.

    4. Agency / consulting invoices

    If you run an agency alongside the newsletter, Stripe Invoices replaces every invoicing tool you’ve used. Send a hosted invoice link. Client clicks, pays, you get notified, accounting reconciles via the Stripe export. Free if the invoice gets paid by card (you pay the standard processing fee), free if paid by ACH.

    The four concepts that trip up newsletter operators

    These are the four things that, in our experience, every operator runs into in their first month and doesn’t fully understand until month three.

    Checkout vs Payment Links vs Pricing Tables

    Three Stripe products that look similar but solve different problems:

    • Checkout — a Stripe-hosted page you redirect to. Best for paid subscriptions and most one-off products. Two lines of code.
    • Payment Links — a single static URL Stripe generates from the dashboard. No code at all. Best for tipping, ebooks, anything where you don’t need a custom checkout flow.
    • Pricing Table — an embedded HTML block (a couple of lines of code) that shows multiple tiers side by side. Best for subscription-with-tier-comparison pages.

    Most operators pick the wrong one because the docs make Checkout sound default. For a single product or single tier, use a Payment Link. For “monthly vs annual vs founding member” comparison, use a Pricing Table. Use Checkout when you actually need fields the others don’t support (custom metadata, B2B tax IDs, complex flows).

    Webhooks

    Webhooks are HTTP callbacks Stripe fires when something happens in your account (payment succeeded, subscription cancelled, card failed). Without webhooks, your site doesn’t know when someone pays or unsubscribes — you have to poll the Stripe API or check the dashboard manually.

    The mistake operators make: skipping webhooks because the platform “seems to work without them.” Then a subscriber cancels, Stripe stops billing, but your site keeps showing them as a paid subscriber for weeks. Or a card fails, Stripe stops collection, but your welcome email keeps going to a churned customer. Set up webhooks on day one. The single endpoint your platform exposes (e.g. /wp-json/otts-pro/v1/stripe/webhook) is the difference between a working paid-newsletter system and a broken one.

    Customer Portal

    The Customer Portal is a Stripe-hosted page where your subscribers can manage their own subscription — change card, switch from monthly to annual, cancel, view invoices. It’s free, takes about an hour to enable, and prevents 100% of “how do I cancel” support emails.

    If you don’t enable it, every cancellation request becomes a manual ticket where you log into the Stripe dashboard, find the customer, click Cancel, and email them confirmation. At 100 paid subscribers this happens once a week. At 1,000 it happens daily. Enable the Customer Portal on day one and link to it from your welcome email.

    Smart Retries / dunning

    Stripe’s “Smart Retries” feature retries failed card charges on a schedule (3 days later, 5 days later, 7 days later). Stripe also handles the customer-facing “your card failed, please update it” emails. This is dunning, and it recovers something like 30–40% of payments that would otherwise be lost.

    It’s not on by default for every account. Go to the Billing settings → Subscription and emails → enable both Smart Retries and the failed-payment emails. Most operators discover this exists after watching their MRR drop unexpectedly because expired cards weren’t being recovered.

    Setup, in the order to actually do it

    1. Create a Stripe account at dashboard.stripe.com/register. The signup is fast. Use your business email, not personal.
    2. Activate the account. Stripe asks for business details — legal name, registered address, tax ID, bank account, ID document for the responsible person. Most US accounts activate within an hour; business-entity verification can take 1–2 business days. Do this before you launch your paid tier; activation delays after you’ve taken pre-orders are stressful.
    3. Set up the bank account for payouts. Daily payouts are the default. If your bank charges per deposit, switch to weekly.
    4. Enable the Customer Portal in Settings → Billing → Customer Portal. Configure what subscribers can change themselves (recommended: cancel, update card, change plan, download invoices).
    5. Set up products + prices in the Stripe dashboard, not in code. Define a “Newsletter Subscription” product with monthly and annual prices. Price IDs (price_xxx) are what your platform references.
    6. Set up webhooks pointing at your platform’s webhook endpoint. Subscribe to at minimum: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed.
    7. Configure tax handling via Stripe Tax. Turn it on the moment you sell internationally; for US-only sellers you can defer until you cross state-level economic nexus (commonly $100k in revenue or 200 transactions in a single state).
    8. Test in test mode before going live. Stripe provides test card numbers (4242 4242 4242 4242 always succeeds, 4000 0000 0000 0002 always declines). Run your full subscribe → cancel → resubscribe flow before flipping the switch.

    Pitfalls, in the order operators usually hit them

    1. The activation delay catches people before launch. You announce the paid tier on Twitter, send your announcement newsletter, and discover the Stripe account isn’t activated yet. New subscribers see “Payments are temporarily unavailable.” Activate the account a week before you intend to take payments.

    2. Tax registration for international and out-of-state sales. The day you take a payment from an EU resident, you’ve technically created a VAT obligation in their country once you cross the threshold. Domestically, US sellers cross state-level sales-tax obligations as soon as you trigger economic nexus (commonly $100k in revenue or 200 transactions per state). Stripe Tax handles the calculation and remittance for both — turn it on. Don’t try to handle this manually.

    3. Currency conversion losses. If your prices are in $ but a UK or EU customer pays in £ or €, Stripe converts at a slightly worse rate than wholesale. Over a year of $10k in international payments, this is roughly $250 in extra fees. For most operators it’s negligible. For high-volume operators with a heavily international audience, multi-currency pricing (separate $, £, € prices for the same tier) is worth the setup time.

    4. Chargebacks. A subscriber forgets they signed up, sees a charge on their statement, calls their bank, and disputes it. Stripe charges $15 per dispute regardless of outcome, plus the original charge gets reversed. The fix: clear billing descriptors (your statement descriptor should be your newsletter name, not “STRIPE PAYMENT”), explicit confirmation emails on first charge, and a visible Customer Portal so cancellations don’t become disputes.

    5. The “trial that never converts.” If you offer a 14-day free trial, plan for 30–50% of trials to never enter a card. Stripe’s Trial requires a card upfront by default; consider whether your business model can handle the conversion drop from card-required vs the support overhead of cardless trials.

    6. Refund policy ambiguity. Newsletter operators often forget they need a refund policy. Stripe’s terms require it. Most newsletters use “no refunds, cancel anytime to stop future charges” — fine, just put it on the pricing page.

    Long-term maintenance

    Monthly: review the Stripe dashboard’s reporting — MRR, churn, failed payments, top products. Stripe’s built-in reporting is enough for most operators; only graduate to ChartMogul or similar if you’re managing multiple products with complex cohort analysis.

    Quarterly: reconcile Stripe payouts with your accounting software. Most accounting tools (QuickBooks, Xero, Wave, FreshBooks) have direct Stripe integrations. Check that fees are categorised correctly and that you’re capturing the right amount as taxable income (revenue, not net of fees).

    Annually: review your dunning configuration. The default Stripe retry schedule is good but not optimal — if your average customer’s card expires every 36 months and you’re seeing more declines than expected, lengthen the retry window. Also review tax thresholds — if you’ve crossed a new sales-tax or VAT registration threshold, Stripe Tax will surface this but you need to act.

    When something breaks: Stripe’s status page (status.stripe.com) is reliable. If checkout’s down, check there before debugging your own code. Outages are rare but they happen.

    When Stripe is the wrong choice

    If you publish entirely on Substack or Beehiiv, you’re already on Stripe — the platform handles the integration and you don’t need to manage it directly. The platform takes 10% of your revenue for that convenience. That’s a fair trade until you outgrow the platform’s limitations.

    If your audience is heavily in countries where Stripe lacks strong local payment methods (most of South America, parts of Africa, India to a lesser extent), look at regional alternatives — Razorpay in India, Mercado Pago in Latin America. Or use Stripe with regional payment-method enabled (iDEAL, Bancontact, etc.) and accept that some markets will be harder to convert.

    If you’re selling primarily B2B with complex invoicing requirements (purchase orders, net-60 terms, custom contracts), Stripe Invoices is fine but accounting-software-native invoicing (QuickBooks, Xero) often integrates better with the rest of the B2B workflow.

    For everyone else, Stripe is the default — and like the other infrastructure decisions in this stack, that’s the highest compliment infrastructure can earn.

    Some links in this post are affiliate links — we earn a small commission if you sign up through them, at no cost to you. We only recommend tools we actually use.