Fixes the AI Settings tab showing two competing links (the legacy “Get a key at console.anthropic.com” plain link and the new 2.0.14 affiliate hint side by side). Now: when no Claude API key is configured, only the affiliate hint renders. When a key is already configured, only the operational “Manage your key at console.anthropic.com” link renders. One link at a time, depending on state.
2.0.15
The affiliate-hint helper from 2.0.14 now also renders per-provider sign-up hints on the Email provider config panel. When a Pro provider (MailerLite, Brevo) is selected and its API key field is empty, an inline “Don’t have a {provider} account yet? Sign up →” link appears beneath the config table. Providers without an affiliate program (Mailchimp, Kit, SES, Resend, SMTP) show nothing — the helper returns empty for unknown slugs. Same compliance posture as 2.0.14: links point to onetwothreesend.com/tools/, not raw affiliate URLs; filterable via otts_affiliate_hint_enabled to disable globally.
2.0.14
Adds a small OTTS_Affiliate_Hint helper that renders an inline “Don’t have a {service} account yet? Sign up →” link next to setup fields when the field is empty. First two call sites: the Claude API key field on Newsletter → Settings → AI Settings, and the Email provider selector on Newsletter → Settings → Provider. Operators who already have credentials never see the hints — the helper only renders when the relevant field is blank. Every link points to onetwothreesend.com/tools/ (a docs page on the publisher’s site, not a raw affiliate URL); affiliate redirection happens there and the FTC disclosure lives on that page. Operators can disable all hints globally via the otts_affiliate_hint_enabled filter (returns false), or replace the service map via otts_affiliate_hint_services. wp.org review note: no external HTTP, no tracking, no site-identifying data — static helper, fully filterable.
2.0.13
Adds three integration points so a Pro extension can replace the Settings → Schedule UI and own scheduling without modifying the free plugin: filter otts_settings_schedule_show_default hides the legacy schedule form when an extension takes over, action otts_settings_schedule_render_pre lets an extension inject a replacement notice, and filter otts_scheduler_register_default_cron suppresses the default otts_scheduled_send cron registration when an extension provides its own. Free plugin behaviour is unchanged without those hooks.
2.0.12
Send reliability overhaul. Per-recipient failures are now classified as transient (rate limit, network blip, 5xx — retry), permanent (invalid email, 4xx — never retry, mark subscriber bounced), or system (auth failure, suspended account — halt the send and email the admin). A new wp_otts_send_retries table holds transient failures; a 5-minute cron worker re-fires them with exponential backoff (5m → 15m → 45m → 2h → 6h) up to 5 attempts. Subscribers get new bounce_state, soft_bounces, last_bounce_at, and last_delivery_at columns. The Resend provider now returns structured WP_Error values with a category so the classifier can act on them without re-parsing the response. A new “Send Health” admin page (Newsletter → Send Health) shows pending retries, bounced subscribers, recently resolved retries, and recent send results — and an admin notice fires whenever a send finishes with any non-success rows.
2.0.11
Resend provider now retries on HTTP 429 with backoff. Resend caps free/default accounts at 5 requests per second; sequential sends to 6+ subscribers were hitting the rate limit on later recipients, and the failure was recorded but never retried — so those recipients silently never got the email. The send loop is unchanged; the provider retries up to 3 times with Retry-After honoured (or 250ms default) before giving up.
2.0.10
Welcome email now ends with the standard footer + working unsubscribe link (the same one broadcast newsletters use). The default body text already promises “every email has an instant unsubscribe at the bottom” — until this release, the welcome email had no footer at all, so the link was missing. Looks up the new subscriber’s token to build the URL, falls back to no footer if for any reason the token can’t be loaded.
Sidebar menu label changed from “Newsletter” to “One Two Three Send”. Submenu items (Dashboard, Newsletters, Subscribers, Settings, etc.) keep their original names — those describe specific features, only the top-level brand label changes.
2.0.9
Welcome email body now supports rich HTML — paste headings, lists, emoji links, and CTA buttons into the body field at Newsletter → Settings → Welcome Email and they render. Bodies without any HTML tags still get the previous plain-text + wpautop treatment, so existing setups carry over unchanged.
2.0.8
Signup forms gained a “Redirect after signup” field (Newsletter → Signup Forms → edit form). When set, the subscriber is redirected to that URL after a successful signup instead of seeing the inline success message. The token {email} in the URL is replaced with the URL-encoded email so a follow-up page (e.g. a Stripe-checkout pricing page) can pre-fill the address. Leave blank to keep the existing inline-message behaviour.
2.0.7
Docs: added a “Useful links” section in the Description with pointers to the features overview, documentation, pricing, privacy policy, and contact page on onetwothreesend.com. No code changes.
2.0.6
Docs: clarified that the Claude API key is OPTIONAL — the plugin works fine for hand-written newsletters without it. The AI features (Generate, Rewrite, Shorten, Expand, Fix grammar, subject suggestions, tone check) only run when you click them, so a key is only needed if you want them. Updated the FAQ and install steps accordingly.
2.0.3
Newsletters can now be marked Free or Paid from the edit screen. Free is the default and sends the full body to every active subscriber. The companion pro plugin applies the paywall when the mode is Paid.
Added filter otts_send_recipients so pro-plugin Stripe paywall can segment free vs paid subscribers per newsletter.
Added filter otts_render_for_subscriber so pro-plugin paywall can substitute a teaser + Subscribe CTA when a free subscriber receives a paid-newsletter send.
Added extension points on the Settings page: otts_settings_tabs filter, otts_render_settings_tab_{tab} and otts_save_settings_{tab} actions, so companion plugins can add their own tabs without modifying free-plugin files.
2.0.2
Fix: differentiated Plugin URI and Author URI in the plugin header as required by the wordpress.org submission check.
2.0.1
wordpress.org compliance pass based on Plugin Check report.
Added translator comments to every translatable string with placeholders.
Ordered placeholders (%1$s, %2$s) in strings with multiple values.
Switched file operations to WP_Filesystem-aligned helpers (wp_handle_upload, wp_delete_file).