Complete documentation for WarmySender. Setup guides, troubleshooting, and help resources for email warmup, cold email campaigns, LinkedIn automation, and more.
Welcome to WarmySender! Follow these steps to get up and running:
Connect your first mailbox — Go to Mailboxes, click 'Add Mailbox', and enter your IMAP/SMTP credentials. For Gmail and Outlook, you need an App Password (see Provider Setup Guides below).
Enable warmup — Once connected, go to Warmup and enable it for your mailbox. The system will start sending and receiving warmup emails automatically to build your sender reputation.
Wait 2-3 weeks — Let warmup run to establish a healthy reputation. Monitor your Health Score (aim for 70+) and Inbox Rate (aim for 80%+) on the Warmup dashboard.
Set up DNS records — While warming up, configure SPF, DKIM, and DMARC records for your sending domain. This is critical for inbox placement.
Create your first campaign — Once your health score is above 70, go to Campaigns and create your first email sequence. Start with a small daily sending limit (20-30 emails/day) and increase gradually.
Monitor results — Use Analytics to track open rates (aim for 40%+), reply rates (aim for 5%+), and bounce rates (keep below 3%). Check your Unified Inbox for replies.
Tip: Complete the in-app product tour for a guided walkthrough. You can replay it anytime from Settings > Account > Product Tour.
Select your email provider (Gmail, Outlook, Hostinger, Zoho, etc.) or choose Custom IMAP/SMTP.
Enter your full email address as the username.
Enter your password — for Gmail and Outlook, you must use an App Password (not your regular password). For Hostinger, use your regular email password. See the Provider Setup Guides below for provider-specific instructions.
The SMTP and IMAP server settings will auto-fill based on your provider. Verify them against the Provider Setup Guides if you have a custom setup.
Click 'Test Connection' to verify everything works before saving.
Once connected, your mailbox will show a green 'Connected' status.
You can connect multiple mailboxes to your workspace. Each mailbox can be assigned to campaigns independently. All paid plans (Pro, Business, Enterprise) include unlimited mailboxes. Free plan includes 1 mailbox, Lite includes 3.
If connection fails, check the Troubleshooting section below for common errors like 'Authentication failed' or 'Connection refused'.
A detailed comparison of all WarmySender subscription plans to help you choose the right one.
Plan Overview (monthly billing):
Pro — $14.99/month (most popular, includes 7-day free trial)
Business — $29.99/month (for growing teams)
Enterprise — $69.99/month (for agencies and high-volume senders)
Annual Billing (save 40% — limited time):
Pro — $8.99/month ($107.88/year)
Business — $17.99/month ($215.88/year)
Enterprise — $41.99/month ($503.88/year)
How the limited-time 40% annual offer works:
The 40% discount is evergreen but framed with a real end-of-month deadline that resets monthly — so the urgency is real (the date you see is the actual end of this calendar month UTC) but the discount itself does not actually disappear when the date hits.
Existing annual subscribers (pre-2026-04-29) keep their original 25% price — they are grandfathered at the rate they signed up for and renew at that same Stripe price ID until they cancel or switch tiers.
Promo codes can stack on top of the 40% (so a 10% off code at checkout makes the total ~46% off list price).
LinkedIn seats are unaffected — they remain monthly-only at $9/seat/month.
Monthly Email Quota:
Pro: 10,000 emails/month (≈333/day)
Business: 100,000 emails/month (≈3,333/day)
Enterprise: 300,000 emails/month (≈10,000/day)
Connected Mailboxes:
All paid plans: UNLIMITED mailboxes
There is no cap on the number of email accounts you can connect and warm up on any paid plan (Pro, Business, or Enterprise)
Free tier: 1 mailbox
Email Warmup:
Included on ALL paid plans at no extra cost
Uses the A.H.D.E. (Adaptive Health-Driven Engine) algorithm
Warm up as many mailboxes as you want — there is no per-mailbox fee
Team Members (Seats):
Pro: 2 members (you as the owner + 1 invited team member)
Business: 4 members (you + 3 invited)
Enterprise: 4 members (you + 3 invited)
Each member gets their own login and can access mailboxes, campaigns, and analytics within the workspace
Unified inbox, analytics, and all other Pro features
How to Start Your Trial:
Sign up at warmysender.com
Click 'Start 7-Day Free Trial' on the Pro plan
No credit card needed — you get instant access
Start connecting mailboxes and setting up warmup immediately
During Your Trial:
A blue banner shows how many days remain
3 days before expiry, you will receive an email reminder
You can upgrade to a paid plan at any time during the trial
What Happens When the Trial Ends:
If you do NOT subscribe: Your account is automatically downgraded to a restricted state. You can still log in but can only access the Billing page to subscribe. Active campaigns and warmup are paused.
If you DO subscribe before the trial ends: Your account seamlessly transitions to the paid plan with no interruption. All your mailboxes, campaigns, and data are preserved.
After Trial Expiry — How to Re-Activate:
Log in to your WarmySender account
You will be redirected to the Billing page
Choose a plan (Pro, Business, or Enterprise) and subscribe
Your account is immediately re-activated with all your data intact
Paused campaigns and warmup can be resumed
Trial Limits:
One free trial per workspace
Disposable/temporary email addresses are not accepted for trial sign-up
The trial is only available on the Pro plan ($14.99/month after trial)
Upgrading During Trial:
You can upgrade to Business or Enterprise at any time during your trial
Upgrading starts your paid subscription immediately
No charge for the trial period — billing begins at the upgrade date
Get your first email campaign running in 15 minutes with this condensed guide.
Minute 1-3: Connect Your Mailbox Go to Mailboxes > Add Mailbox. Select your provider (Gmail, Outlook, etc.) and enter your credentials. For Gmail/Outlook, use an App Password — see Provider Setup Guides below for instructions.
Minute 4-6: Add Prospects Go to Prospects > Import. Paste or upload a CSV with at least an email column. Start with 50-100 contacts to test your messaging.
Minute 7-10: Create Your Campaign Go to Campaigns > Create Campaign > Email Campaign. • Name your campaign • Select your prospect list • Write Step 1: Subject line + body with merge tags ({{firstName}}, {{company}}) • Add 1-2 follow-up steps with 3-day delays • Assign your mailbox
Minute 11-13: Configure Settings • Daily limit: 20-30 emails/day (conservative start) • Sending window: 9 AM - 5 PM in your prospects' timezone • Active days: Monday through Friday • Enable: Stop on Reply, Stop on Bounce
Minute 14-15: Launch Preview your email with sample data. Click Activate. Your campaign starts sending within the next sending window.
Important: This quick start skips warmup for speed. For best results, warm up your mailbox for 2-3 weeks first (see 'How Email Warmup Works'). Without warmup, start with very low daily volume (10-15 emails/day) and monitor your Health Score closely.
Display Name — Your name shown to team members and in sender merge tags ({{sender_name}}).
Email — Your login email address. Used for billing receipts and support communication. You can change your email by clicking 'Change Email' — a verification code will be sent to your new address to confirm the change.
Timezone — Your default timezone for sending windows and analytics. Individual campaigns can override this.
Security:
Change Password — Update your account password. Requires current password for verification.
Active Sessions — View and manage your active login sessions across devices.
Session Duration — Sessions last 30 days by default. After expiry, you will need to log in again.
Workspace Settings:
Workspace Name — The name displayed in the sidebar and workspace switcher.
Default Sending Window — Set default hours for new campaigns (can be overridden per campaign).
You can adjust a mailbox's daily sending limit at any time without disconnecting or reconnecting the mailbox. The change is live and takes effect on the very next scheduler tick — no campaigns are disrupted, no authentication is re-requested, and no in-flight sends are lost.
Where to Find It 1) Go to the Mailboxes page. 2) Find the mailbox row you want to adjust. 3) Click the row's dropdown menu (the '...' or gear icon) and select 'Edit Daily Limit'. 4) The same option is available from the mailbox's View Details page if you prefer a fuller view before editing. 5) Enter the new daily limit and save. The value is stored on the mailbox's `dailyLimit` field and is picked up immediately by the next scheduler cycle.
Recommended Ranges • Brand-new mailbox (first 2 weeks): 20-30 emails/day. Stay conservative while warmup builds reputation. • Warmed-up mailbox (health score 70+, 2+ weeks of warmup): 50-100+ emails/day is safe. Increase gradually, not all at once. • Never exceed 500/day per mailbox — that is WarmySender's global per-mailbox hard cap and the practical ceiling for any single inbox.
How It Interacts With Campaign-Level Caps WarmySender enforces THREE sending caps and the MINIMUM of the three always wins. Sends stop the moment the first cap is hit: • Mailbox `dailyLimit` — the value you set on this page. • Campaign `dailySendLimit` — a cap per campaign across all of its mailboxes. • Campaign-mailbox `maxSendsPerMailboxPerDay` — a cap on how much a single mailbox can send for a single campaign.
Example: mailbox limit 100, campaign limit 50, per-mailbox-per-campaign limit 30 → only 30 sends will happen through that mailbox for that campaign today.
Warmup Traffic Is Counted Separately Warmup sends use the `warmupTargetDailyVolume` field, not `dailyLimit`. Raising or lowering your campaign daily limit does not affect how many warmup emails your mailbox sends. To adjust warmup volume, go to the Warmup settings for the mailbox instead.
Changes Apply to the Current Day The daily limit is enforced against today's running send count. If the mailbox has already sent 25 emails today and you raise the limit from 25 to 30, it can still send 5 more today. If you lower the limit below the current count, sending simply pauses until tomorrow — no error, no disruption.
TL;DR: If you just want to change a setting (like the daily sending limit), DO NOT disconnect and reconnect. Use the Edit Daily Limit option on the Mailboxes page — it is live and non-disruptive. Only delete-and-reconnect when the mailbox is genuinely broken (expired credentials, provider migration, persistent auth errors). Deleting creates a NEW mailbox record with a new internal ID, which requires a small manual follow-up step to keep campaigns flowing.
What Survives a Delete Prospects are NEVER deleted when you remove a mailbox. Specifically: • Prospect rows remain in the database with their full sequence history. • The sequence step cursor (which email they are on) is preserved — leads will NOT restart at Email 1. • Reply-thread message IDs (`lastSentMessageId`) are preserved, so threaded replies continue to stitch correctly. • Campaign enrollments, suppression entries, opens, clicks, and replies all remain intact.
What Happens Technically When you delete a mailbox, the system runs a safe cleanup: every in-flight prospect that was assigned to that mailbox has its `mailbox_id` nulled (set to NULL, not deleted). The prospect stays in the campaign, waiting for the scheduler to pick a new mailbox from the campaign's pool on the next tick. The next scheduled send is pushed out by an hour so nothing fires immediately.
REQUIRED Action After You Reconnect This is the step people forget: after reconnecting, manually add the newly-connected mailbox to each affected campaign's mailbox pool. • Go to Campaign → Settings → Mailboxes. • Toggle the new mailbox on (or add it if it is not listed). • Save.
Without this step, the affected prospects have no mailbox to send from. The scheduler will keep rescheduling them +1 hour indefinitely, and your campaign will appear 'running' but produce zero sends until a valid mailbox is available.
Thread Continuity Is Safe Replies to Email 1 and Email 2 continue to thread correctly even after a reconnect. Thread IDs are stored on the prospect row (`lastSentMessageId`), not on the mailbox, so a new mailbox ID does not break References/In-Reply-To stitching.
Daily Limit Changes — Do Not Disconnect If your only goal is to change the daily sending limit, use the 'Edit Daily Limit' option on the Mailboxes page instead. It is live, requires no reconnect, and preserves the mailbox's internal ID — meaning every campaign keeps sending without any manual pool update. See the 'Editing a Mailbox's Daily Sending Limit' guide above.
Warmup-Enabled Mailboxes Warmup stats (health score, inbox rate, spam rate, 7-day rolling history) are tied to the mailbox record. When you delete and reconnect, those stats reset because it is technically a new record. Plan for a short re-warmup period (a few days to a week) before running heavy campaign volume on the reconnected mailbox — this is another reason to avoid unnecessary reconnects.
WarmySender's email warmup system automatically builds your sender reputation by exchanging emails between real mailboxes in our network. Here is how it works:
Sending: Your mailbox sends warmup emails to other WarmySender users' mailboxes according to your daily volume settings. The system starts with low volume and gradually increases over time.
Receiving: Other WarmySender users' mailboxes send emails to yours. Your mailbox automatically opens, marks as important, and replies to these emails — signaling to email providers (Gmail, Outlook, Yahoo) that your messages are wanted.
Spam Rescue: If any warmup emails land in your spam/junk folder, WarmySender automatically detects them and moves them back to your inbox. This 'rescues' your reputation by training email providers that your messages belong in the inbox.
Peer Selection: The system intelligently pairs your mailbox with other healthy mailboxes. It prefers cross-provider pairing (e.g., Gmail sends to Outlook) for better deliverability signals. Unhealthy mailboxes with high spam or bounce rates are excluded from the peer pool.
Health Scoring: Your mailbox gets a Health Score (0-100) calculated from inbox placement rate, spam rate, and bounce rate over a 7-day rolling window. Score above 80 = Excellent, 60-79 = Good, 40-59 = Fair, below 40 = Critical.
The warmup process runs 24/7 within your configured time window. Most mailboxes reach a healthy score within 2-3 weeks.
Normal — Balanced ramp (0.12 growth rate). Good default for most mailboxes.
Aggressive — Fastest ramp (0.20 growth rate). Only for established domains with existing reputation.
Strategy Modes — The system uses intelligent strategies that auto-evolve based on your mailbox's age and performance:
New Domain — Starts at 1 email/day, max 40/day. For brand-new domains with zero history.
New Mailbox — Starts at 3/day, max 60/day. For new mailboxes on established domains.
Dormant — Starts at 3/day, max 40/day. Auto-applied when a mailbox is idle for 14+ days.
Maintenance — Starts at 15/day, max 30/day. Steady-state for fully warmed-up mailboxes.
Recovery — Starts at 5/day, max 30/day. Auto-applied when bounce or spam rates spike.
New Domain Ramp Table (day-by-day) Here is what the typical New Domain ramp looks like at Normal speed, assuming healthy bounce and complaint metrics throughout:
Day 1: 1 email/day Day 2-3: 1-2 emails/day Day 4-5: 2-3 emails/day Day 6-7: 3-4 emails/day Day 8-9: 5-6 emails/day Day 10-11: 7-8 emails/day Day 12-13: 9-10 emails/day Day 14: ~11-12 emails/day Day 21: ~18 emails/day (auto-graduates to New Mailbox mode) Day 30: ~30 emails/day Day 45+: 40 emails/day (New Domain cap)
Maintenance mode (after graduation): starts at 15/day and grows to 30/day max.
Note: If you are at the start of Maintenance mode and want to send more, you will need to wait for the system to ramp you up based on bounce and complaint metrics, OR add additional inboxes to distribute volume. The ramp is intentionally gradual to protect your sender reputation — pushing harder increases the risk of landing in spam.
Automatic Strategy Transitions (A.H.D.E. System):
New Domain auto-promotes to New Mailbox after 30 days
New Mailbox auto-transitions to Maintenance after 21 days of active sending
If bounce rate exceeds 10% or spam rate exceeds 5%, the system auto-switches to Recovery mode
After successful recovery, the system returns to your previous mode
If you manually set a strategy, auto-evolution is paused for 30 days
Daily Volume — Set your target warmup emails per day. The system ramps up to this target based on your ramp speed. Start low (5-10) for new mailboxes.
Time Window — Set the hours and timezone during which warmup emails are sent (default: 24 hours, all day).
Health Score — Monitor your score (0-100): Excellent (80+, green), Good (60-79, blue), Fair (40-59, yellow), Critical (below 40, red). Keep it above 70 before starting campaigns.
Your warmup emails are protected by a multi-layered defense system that works around the clock to ensure reliable delivery and safeguard your sender reputation.
Layer 1: Global Domain Blocklist Our team maintains a curated blocklist of domains that are excluded from the warmup peer pool. If a domain is known to have persistent delivery issues — such as invalid mailboxes, expired accounts, or infrastructure problems — it is blocked system-wide so your warmup emails are never sent to unreliable destinations.
Layer 2: Automatic MX/SMTP Health Checking A background service runs every 2 hours to verify the DNS records and mail server reachability of every domain in the warmup pool. If a domain's mail server becomes unreachable or stops responding, it is automatically excluded from peer selection. When the domain comes back online and passes health checks again, it is restored automatically — no manual intervention needed.
Layer 3: IMAP Bounce Detection During regular inbox scanning, the system monitors for bounce-back messages and delivery failure notifications (also known as NDRs). If a particular domain causes 3 or more bounces within a 7-day window, it is automatically added to the blocklist. This catches delayed delivery failures that may pass initial send checks but ultimately fail.
Additional Safeguards:
Spam Rescue — Warmup emails that land in spam or junk folders are automatically detected and moved back to your inbox, training email providers that your messages are legitimate.
Cross-Provider Pairing — The system prefers pairing mailboxes across different providers (e.g., Gmail to Outlook) for stronger deliverability signals.
Health Scoring — Every mailbox receives a health score. Mailboxes with poor scores are excluded from the peer pool to protect other users.
Pool Depletion Protection — If most peers become temporarily unavailable, the system falls back gracefully rather than blocking your warmup entirely. Your warmup continues with available healthy peers.
All of these protections run automatically in the background. You do not need to configure or manage anything — just enable warmup and the system handles the rest.
Every mailbox in WarmySender receives a Health Score from 0 to 100 that reflects its current sender reputation based on warmup performance.
How the Score Is Calculated Your health score is computed from three key metrics measured over a rolling 7-day window: • Inbox Rate — The percentage of warmup emails that land in the recipient's inbox (not spam). Higher is better. • Spam Rate — The percentage of warmup emails that end up in spam or junk folders. Lower is better. • Bounce Rate — The percentage of warmup emails that fail to deliver. Lower is better.
The score penalizes bounces most heavily (they have the greatest negative impact), followed by spam placement, then low inbox rates.
Score Ranges • Excellent (80-100) — Your mailbox has a strong reputation. Safe to run campaigns at full volume. • Good (60-79) — Solid reputation with room for improvement. Campaigns can run, but monitor closely. • Fair (40-59) — Reputation needs attention. Consider reducing campaign volume and letting warmup strengthen your score. • Critical (below 40) — Significant reputation issues detected. The system may auto-switch your mailbox to Recovery mode to protect your domain.
What Affects Your Score • Emails landing in spam folders lower your score. • Bounced or undeliverable emails reduce your score. • Successful inbox placements and positive engagement (opens, replies) improve your score.
How the System Uses Scores • Mailboxes with low scores are automatically excluded from the warmup peer pool to protect other users. • If your score drops sharply, the system may trigger Recovery mode, which reduces volume and focuses on rebuilding reputation. • Once your score recovers, normal warmup volume resumes automatically.
Tips for a Healthy Score • Keep your score above 70 before starting any email campaigns. • Verify your DNS records (SPF, DKIM, DMARC) are correctly configured. • Monitor your bounce rate — a sudden spike often indicates a DNS or server issue. • Let warmup run consistently for 2-3 weeks before judging results. • If your score drops, check your mailbox connection and DNS settings before taking other action.
Spam Rescue is one of WarmySender's most powerful features for building your sender reputation. It works automatically to ensure warmup emails always end up in your inbox — even when email providers initially route them to spam.
How Spam Rescue Works During regular IMAP scans, WarmySender checks both your inbox and your spam/junk folders. When a warmup email is found in spam, the system identifies it using internal tracking tokens and automatically moves it back to your inbox.
Why This Matters Every time a message is moved from spam to inbox, it sends a strong signal to your email provider (Gmail, Outlook, Yahoo, and others) that emails from that sender are legitimate and wanted. Over time, these signals train the provider's spam filters to trust your domain, improving your overall inbox placement rate.
Automatic and Hands-Free Spam rescue happens entirely in the background — you do not need to manually check your spam folder or move any emails. The system handles detection and rescue automatically during each scan cycle.
Impact on Your Health Score Your inbox placement rate — including emails successfully rescued from spam — contributes directly to your mailbox health score. A high rescue success rate helps maintain a strong score, while emails that remain undetected in spam would lower it.
Works Across All Providers Spam rescue is compatible with all connected email providers, including: • Gmail and Google Workspace • Outlook and Microsoft 365 • Yahoo Mail • Any custom IMAP-compatible email service
The system adapts to each provider's folder structure and naming conventions (Spam, Junk, Bulk Mail, etc.) to ensure comprehensive coverage.
No Configuration Required Spam rescue is enabled by default for all mailboxes with warmup active. Simply connect your mailbox, enable warmup, and the system takes care of the rest.
Warmup and campaign emails share your daily sending capacity, so understanding how they interact is important for a successful outreach strategy.
Shared Daily Quota Your subscription plan sets a total daily sending limit per mailbox. Both warmup emails and campaign emails count toward this limit. For example, if your plan allows 50 emails per day and warmup sends 20, you have 30 remaining for campaigns.
When to Start Campaigns Before launching your first campaign, make sure: • Warmup has been running for at least 2-3 weeks. • Your mailbox Health Score is 70 or above. • Your DNS records (SPF, DKIM, DMARC) are properly configured. • Your bounce rate is below 3% over the last 7 days.
Keep Warmup Running Never fully disable warmup once you start campaigns. Instead, reduce warmup volume to make room for campaign sends. The system automatically adjusts — once a mailbox enters Maintenance mode, warmup volume stays low (15-30 emails per day) while keeping your reputation active.
Balancing Volume If you need more daily capacity for campaigns, you can lower your warmup daily limit. A good balance is keeping warmup at 15-20 emails per day while dedicating the rest to campaigns. This ensures ongoing reputation maintenance without starving your outreach.
Automatic Safety If your campaign sends cause bounce or spam rates to spike, the warmup system detects this through the shared health metrics and may trigger Recovery mode. This is a protective measure — reduce campaign volume and let your reputation recover before resuming.
If your mailbox Health Score drops significantly, follow these steps to diagnose and recover.
Step 1: Check Your Mailbox Connection Go to your mailbox settings and verify the connection status is 'Connected'. A disconnected or expired OAuth token means warmup emails cannot be sent or received, which will cause your score to drop.
Step 2: Verify DNS Records Check that your SPF, DKIM, and DMARC records are correctly configured in your domain's DNS settings. Missing or misconfigured DNS is the most common cause of sudden score drops. Use the Analytics page to verify your DNS setup.
Step 3: Review Bounce Rate A spike in bounces (above 5%) strongly impacts your score. Common causes include: • DNS records changed or removed. • Mail server configuration issues. • Sending to outdated or invalid email addresses in campaigns.
Step 4: Pause Campaigns Temporarily If your score is below 50, consider pausing active campaigns until your score recovers above 60. Campaign sends with a damaged reputation will have poor deliverability and can make the problem worse.
Step 5: Let Recovery Mode Work If the system has auto-switched your mailbox to Recovery mode, do not override it. Recovery mode reduces daily volume and focuses on rebuilding your reputation through carefully managed warmup sends. Most mailboxes recover within 2-4 weeks.
Step 6: Monitor Daily Check your score daily during recovery. Look for a steady upward trend. Small daily fluctuations are normal — focus on the 7-day trend rather than individual days.
When to Contact Support If your score does not improve after 3 weeks of consistent warmup with good DNS, or if you see a sudden drop with no apparent cause, reach out for assistance.
Best practices for warming up multiple domains simultaneously.
Why Use Multiple Domains? • Protect your primary domain — Use secondary domains for cold outreach so your main business domain stays clean. • Scale volume safely — Each domain can send a limited amount per day. More domains = more total capacity. • Risk isolation — If one domain gets flagged, your other domains continue working.
Domain Setup Strategy:
Buy 2-5 secondary domains similar to your primary (e.g., if you own acme.com, buy acmehq.com, getacme.com, tryacme.com).
Set up SPF, DKIM, and DMARC on each domain before connecting.
Create 1-3 mailboxes per domain (don't create too many on a single domain).
Point each domain to your website or create a simple landing page — email providers check if the domain has real web presence.
Warmup Approach:
Start all domains in warmup simultaneously — there is no need to stagger.
Use Conservative ramp speed for all new domains.
Each mailbox warms up independently — they each build their own reputation.
Wait until ALL domains reach Health Score 70+ before starting campaigns.
Campaign Distribution:
Assign mailboxes from different domains to the same campaign using mailbox rotation.
Round-robin rotation distributes sends evenly across domains.
If one domain's health drops, disable its mailboxes from the campaign without stopping others.
Monitoring:
Check each domain's SPF/DKIM/DMARC status in Analytics > Mailboxes.
Monitor per-mailbox Health Scores — one unhealthy domain should not affect others.
If a domain enters Recovery mode, reduce or pause campaigns for that domain while it recovers.
Common Mistakes:
Using domains that look spammy (random characters, suspicious TLDs) — buy professional-looking domains.
Not setting up DNS records on secondary domains.
Putting too many mailboxes (5+) on a single new domain.
Starting campaigns before warmup reaches healthy scores on all domains.
Q: How long should I warm up before sending campaigns? A: At minimum 2-3 weeks for existing domains, 4-6 weeks for brand-new domains. Wait until your Health Score is consistently above 70.
Q: Can I run warmup and campaigns at the same time? A: Yes, and you should. Both share your daily sending quota. The system auto-adjusts — in Maintenance mode, warmup uses 15-30 emails/day while leaving the rest for campaigns.
Q: Why did my warmup strategy change automatically? A: WarmySender's A.H.D.E. system auto-evolves strategies based on your mailbox age and performance. For example, New Domain promotes to New Mailbox after 30 days, and high bounce rates trigger Recovery mode.
Q: What if my Health Score is stuck and won't improve? A: Check: (1) DNS records are correct (SPF, DKIM, DMARC). (2) Mailbox is connected and active. (3) No campaigns causing high bounce rates. (4) Give it 2-3 weeks of consistent warmup.
Q: Should I warm up on weekends? A: Yes. Warmup runs 24/7 by default and sending on weekends helps build natural engagement patterns. Campaign sends are separate — those follow your configured schedule.
Q: How many warmup emails per day is optimal? A: Start with 5-10 for new domains. The system ramps up automatically based on your ramp speed. At full maturity, Maintenance mode sends 15-30/day.
Q: Will warmup emails be visible to my contacts? A: Warmup emails are sent to other WarmySender users' mailboxes, not to your contacts. The system automatically manages them — they are not visible in your regular inbox flow.
Q: Can I warm up a mailbox I have been using for years? A: Yes. The system detects established mailboxes and assigns an appropriate strategy. Existing reputation is preserved — warmup reinforces and maintains it.
Q: What happens if I disable warmup? A: Your sender reputation gradually decays without active warmup. If you are running campaigns, keep warmup on in Maintenance mode to sustain your deliverability.
The Dashboard Health Score is a composite workspace-wide score (0-100) that reflects the overall health of your outreach across all systems — email campaigns, warmup, LinkedIn, and campaigns. It is different from the per-mailbox Warmup Health Score.
How the Dashboard Score Is Calculated The score combines four sub-scores with dynamic weighting:
1) Email Sub-Score (40-50% weight) — Based on your campaign performance over the last 30 days: • Bounce rate: below 2% = excellent, below 5% = good, above 5% = poor • Open rate: above 30% = excellent, above 20% = good, below 20% = poor • Reply rate: above 5% = excellent, above 2% = good, below 2% = poor This sub-score is the average of all three metrics.
2) Warmup Sub-Score (30-40% weight) — Based on warmup performance:
DNS health: percentage of mailboxes with valid SPF and DKIM records
3) LinkedIn Sub-Score (20% weight, only if LinkedIn accounts exist) — Based on:
Average account health score across connected LinkedIn accounts
Restrictions: any active restrictions heavily reduce this score
4) Campaign Sub-Score (10% weight) — Based on:
Whether you have active running campaigns (yes = good)
High bounce rate penalty (above 5% with 50+ sends = -30 points)
Dynamic Weighting Only systems you are actively using contribute to the score. If you have no LinkedIn accounts, the LinkedIn sub-score is excluded and the remaining weights are redistributed proportionally. If you have no campaigns, the campaign sub-score is excluded. This prevents unused features from penalizing your score.
Why Your Dashboard Score Differs from Warmup Scores Your per-mailbox warmup health scores (shown on the Warmup page) measure only warmup email deliverability — inbox rate, spam rate, and bounce rate from warmup emails. The Dashboard Health Score includes campaign performance, LinkedIn health, and DNS status. You can have perfect warmup scores (100) while the Dashboard Score is lower because campaign open rates are low or LinkedIn has issues.
Common Reasons the Dashboard Score Drops • Low campaign open rates (below 20%) — This is the most common cause. If you just started campaigns on new domains, open rates may be low initially. • Zero reply rate — No campaign replies yet heavily penalizes the email sub-score. • LinkedIn account needs re-verification — A disconnected or restricted LinkedIn account drops the LinkedIn sub-score significantly. • Missing DNS records — SPF or DKIM not configured on some mailboxes lowers the warmup sub-score. • High bounce rate — Campaign bounces above 5% penalize both the email and campaign sub-scores.
How to Improve Your Dashboard Score • Warm up mailboxes for 2-3 weeks before starting campaigns — this builds reputation for better open rates. • Verify email lists before campaigns — reduces bounces. • Write better subject lines — improves open rates (aim for 30%+). • Keep LinkedIn accounts connected and verified. • Configure SPF, DKIM, and DMARC on all sending domains. • Start campaigns with small volumes (20-30/day) and increase gradually. • Monitor the Analytics page to track which sub-area needs improvement.
Prerequisites — Make sure your mailbox is connected, warmup has been running for 2-3 weeks, and your Health Score is above 70. Set up SPF, DKIM, and DMARC DNS records for your sending domain.
Create Campaign — Go to Campaigns, click 'Create Campaign', and select 'Email Campaign' (you can also choose LinkedIn or Multichannel if you have LinkedIn seats).
Add Prospects — Import contacts via CSV file, paste data directly, add individually, or select from an existing prospect list. You can also use prospects saved from the Leads Database.
4) Write Your Sequence — Create your email steps:
Step 1: Your initial outreach email with a compelling subject line
Use merge tags like {{firstName}}, {{company}}, {{role}} for personalization
Each step can be a new email or a reply to the same thread (threadable)
Configure Sending — Set your daily sending limit (start with 20-30/day), sending window (time of day + timezone), and active days (default: Mon-Fri). Assign one or more mailboxes to the campaign.
Review & Launch — Preview your emails with sample data, verify settings, and activate the campaign.
Monitor — Watch your campaign analytics: open rates, reply rates, bounce rates. Check Unified Inbox for replies. The system auto-pauses if safety metrics are violated (high bounce rate, spam complaints).
Best practice: Start with a small batch (50-100 prospects) to test your messaging before scaling up. Aim for: Open rate 40%+, Reply rate 5%+, Bounce rate below 3%.
Email Campaign — Traditional cold email outreach. Steps include emails with subject lines, body content, and merge tags. Supports multi-step sequences with automated follow-ups, A/B testing, and tracking (opens, clicks, replies, bounces).
LinkedIn Campaign — LinkedIn-only outreach using your connected LinkedIn account. Step types include:
Wait Accept — Pause until the prospect accepts your connection
Send Message — Direct message to connected prospects (8,000 char limit)
Wait Reply — Pause until the prospect replies
View Profile — Visit the prospect's profile (creates a notification)
Engage Post — Like or comment on a prospect's post
Endorse Skill — Endorse a prospect's LinkedIn skill to build rapport before connecting
Send InMail — Premium feature for messaging non-connections
Conditional branches — Route prospects based on whether they accepted or replied
Multichannel Campaign — Combines email and LinkedIn steps in a single sequence. For example: Day 1 view LinkedIn profile, Day 2 send connection request, Day 4 send email, Day 7 send LinkedIn message. This creates multiple touchpoints across channels.
LinkedIn and Multichannel campaigns require an active paid subscription and LinkedIn seats ($9/month per seat). You can create campaigns from the Campaigns page using the 'Create Campaign' dropdown.
Multichannel campaigns let you combine email and LinkedIn outreach in a single sequence for maximum engagement.
Getting Started:
Go to Campaigns Hub and click 'New Campaign', then select 'Multichannel' as the campaign type.
You must have at least one email mailbox connected AND one LinkedIn account connected to create a multichannel campaign.
Building Your Sequence: Mix and match email steps and LinkedIn steps in any order: • Email steps — Send email, follow-up email, reply in thread • LinkedIn steps — View profile, send connection request, send message, send InMail
Example Multichannel Sequence:
Day 0: View LinkedIn profile (creates a notification so the prospect sees your name)
Day 1: Send connection request with a personalized note
Day 3: Send email if not yet connected (reaches them through a different channel)
Day 5: Send LinkedIn message if connected (follow up where the conversation started)
Day 8: Send follow-up email if no reply on either channel
Setting Delays: Configure delays in days and hours between each step. The system respects your sending windows and adds random jitter to keep outreach natural.
Cross-Channel Reply Detection: When a prospect replies on one channel, the entire sequence stops across all channels. An email reply stops pending LinkedIn steps, and a LinkedIn reply stops pending email steps. This prevents awkward double-outreach after someone has already responded.
Monitoring Results: Track multichannel campaign performance from the campaign detail view. You can see per-step metrics for both email (opens, clicks, replies) and LinkedIn (invites sent, accepted, messages delivered, replies) in one unified dashboard.
Merge tags let you personalize every email for each prospect automatically.
Built-in Tags:
{{firstName}} — Prospect's first name
{{lastName}} — Prospect's last name
{{email}} — Prospect's email address
{{company}} — Company name
{{role}} — Job title / role
{{city}} — City
{{country}} — Country
{{industry}} — Industry
{{website}} — Company website
{{phone}} — Phone number
{{linkedinUrl}} — LinkedIn profile URL
LinkedIn-Specific Tags (in LinkedIn campaigns):
{{headline}} — LinkedIn headline
{{location}} — LinkedIn location
{{jobTitle}} — Job title from LinkedIn profile
{{sender_name}} — Your name (the sender)
Sender Tags:
{{sender_name}} — Your display name
{{sender_email}} — Your email address
{{sender_company}} — Your company name
Custom Fields: When importing prospects via CSV, any column not matching a built-in field becomes a custom field. For example, a CSV column 'department' maps to custom:department, and you can use it as {{custom.department}} or {{department}} in your emails. The {{custom.department}} syntax is recommended (and what the variable picker inserts), but the bare {{department}} shorthand also works.
Custom Fields in Subject Lines: Custom fields from your CSV work everywhere — including the subject line. If you import a CSV with a custom:subject_line column, you can set your entire subject to {{custom.subject_line}} or {{subject_line}}. For fully pre-written emails, your subject line could be just {{custom.subject_line | default: 'Quick question'}} — each prospect gets their own unique subject.
Fallback Values: Use the Liquid-style syntax for defaults: {{firstName | default: 'there'}} renders as 'there' if firstName is empty.
Best Practices:
Always preview your email before sending to check how merge tags render
Use merge tags in subject lines for higher open rates
Keep personalization natural — don't over-stuff with tags
Test with a small batch first to catch any empty fields
Spintax lets you create multiple text variations within a single email, so every recipient gets a slightly different version. This improves deliverability by making each email unique and helps avoid spam filters.
Syntax: Wrap your alternatives in curly braces, separated by pipes: {Hello|Hi|Hey} — randomly picks one option per send.
Works In:
Subject lines — Yes, fully supported
Email body — Yes, fully supported
Follow-up steps — Yes, each step can use spintax independently
Examples: Subject: {Quick question|Reaching out|Short intro} about {{company}} Body: {Hope you're doing well|Hope your week is going great}, {{firstName}}. {I wanted to reach out|I'm reaching out|I noticed your work} {about|regarding} {a potential collaboration|an opportunity I think you'd find interesting}.
Multiple spintax blocks multiply your variations:
1 block with 3 options = 3 unique versions
2 blocks (3 × 2 options) = 6 unique versions
3 blocks (3 × 2 × 4 options) = 24 unique versions
The variation count is shown in the editor status bar so you can see your total unique combinations at a glance.
Spintax vs Merge Tags:
Merge tags ({{firstName}}) pull data from your prospect's profile — same value every time for that prospect
Spintax ({Hi|Hello|Hey}) randomly picks one option at send time — different each time
You can combine both: {Hi|Hello} {{firstName}}, {hope you're well|how are you?}
Preview & Testing:
The email editor highlights spintax in yellow so you can spot it easily
Use the Preview panel to see how a resolved version looks
Click the Shuffle button (🔀) in the preview to re-randomize and see different variations
Always send a test email to yourself to verify spintax resolves correctly
Processing Order: 1. Merge tags are resolved first ({{firstName}} → 'Scott') 2. Spintax is resolved second ({Hi|Hello} → 'Hello') 3. HTML formatting is applied last
Best Practices:
Use spintax in subject lines — it dramatically improves deliverability by making each email unique
Keep all options natural and interchangeable (don't mix formal and casual in one block)
Avoid nesting spintax inside spintax — only one level is supported
Combine with merge tags for maximum personalization
Aim for 10+ total variations across your email to ensure uniqueness
Don't confuse spintax braces {} with merge tag braces {{}} — single braces with pipes are spintax, double braces are merge tags
A/B testing lets you compare different email variants to find what works best.
How It Works:
When creating a campaign step, add multiple variants — each with its own subject line and body content.
Each variant gets a weight that determines what percentage of prospects receive it (e.g., 50/50 split for two variants).
As emails are sent, the system tracks open rates, click rates, and reply rates for each variant independently.
The variant assignment is stored per prospect for consistent tracking.
Auto-Optimization: WarmySender can automatically pick the winning variant using statistical analysis: • Enable 'Auto-Optimize' on the campaign step • Set a minimum sample size (default: 100 sends) — the system needs enough data before making a decision • Set a confidence level (default: 95%) — how sure the system needs to be • The system uses a chi-squared statistical test comparing reply rates across variants • When statistical significance is reached, the winning variant gets 100% of future sends • Auto-optimize checks run every hour
What to Test:
Subject lines — Usually the biggest impact on open rates
Opening lines — First sentence determines if the email gets read
Call-to-action — Different asks (meeting, reply, link click)
Email length — Short vs. detailed approaches
Personalization level — More vs. fewer merge tags
Best Practice: Test one variable at a time for clear results. Start with subject line testing as it has the most measurable impact on open rates.
Sending Window — Set the start and end hours for email delivery:
Default: 9 AM to 5 PM (business hours)
Supports overnight windows (e.g., 10 PM to 6 AM) for different regions
If start equals end, the window is 24 hours (always open)
Timezone — All scheduling is timezone-aware using IANA timezone strings (e.g., 'America/New_York', 'Europe/London'). Emails are sent during business hours in the recipient's timezone if you set it correctly.
Active Days — Choose which days of the week to send:
Default: Monday through Friday (weekdays)
You can enable weekend sending for certain industries
Uses 0=Sunday through 6=Saturday notation
How Scheduling Works:
When a prospect is ready for their next step, the system calculates the scheduled send time (step delay + random jitter)
If the scheduled time falls outside your sending window or on an inactive day, it automatically advances to the next valid time
The system scans up to 8 days ahead to find the next valid slot
Random jitter (1-5 minutes) is added between individual sends to avoid pattern detection
Best Practices:
Send during your prospect's business hours, not yours
Tuesday through Thursday typically have the highest open rates
Avoid Monday mornings (inbox overload) and Friday afternoons (weekend mindset)
Morning sends (8-10 AM local time) tend to perform best
WarmySender enforces multiple layers of sending limits to protect your deliverability:
Campaign-Level Limits:
Daily send limit — Max emails per campaign per day (default: 100)
Per-mailbox cap — Max sends from a single mailbox per campaign per day (default: 50)
Per-prospect cap — Max emails to one prospect per day (default: 3)
Per-prospect cooldown — Minimum hours between emails to the same prospect (default: 24)
Mailbox-Level Rate Limits:
2 emails per minute per mailbox
40 emails per hour per mailbox
500 emails per day per mailbox (hard cap across all campaigns)
Plan-Level Daily Limits:
Free / Lite: 17 emails/day
Pro: 333 emails/day
Business: 3,333 emails/day
Enterprise: 10,000 emails/day
Provider-Level Limits:
30 emails per minute across all mailboxes on the same provider
600 per hour, 6,000 per day per provider
Domain-Level Limits:
Per-recipient-domain caps prevent over-sending to any single company (e.g., max emails to @google.com per day)
Backoff System: If any rate limit is hit, the system backs off: 1 minute → 5 minutes → 15 minutes → 1 hour. It resets after 30 successful sends within a 60-minute window.
Best Practice: Start with 20-30 emails/day per mailbox for new campaigns and increase gradually. Use multiple mailboxes to scale volume safely.
Assign multiple mailboxes to a single campaign and WarmySender will automatically rotate between them:
Rotation Modes:
Round Robin (default) — Selects the mailbox with the fewest sends today. This evenly distributes the load across all mailboxes.
Random — Randomly selects from available mailboxes each time.
Weighted — Uses configurable weights per mailbox. A mailbox with weight 3 gets roughly 3x the sends of a mailbox with weight 1.
Mailbox Availability: A mailbox is only used if ALL of the following are true: • It is marked 'Active' on the campaign (you can disable individual mailboxes without removing them) • It is in 'Connected' status (not disconnected or in error state) • It hasn't exceeded its daily per-campaign soft cap • It hasn't exceeded its global daily limit (500 emails/day) • It's not currently rate-limited (in backoff) • It hasn't exceeded the domain daily limit for the recipient's domain
Per-Mailbox Settings (within a campaign):
Weight — Controls rotation priority (default: 1)
Active toggle — Enable/disable without removing
Daily soft cap — Optional per-campaign limit for this mailbox
Capacity Planning: The scheduler pre-calculates available capacity per mailbox before scheduling new sends, accounting for already-sent emails and pending/processing jobs.
Best Practice: Use 3-5 mailboxes per campaign to distribute sending volume and reduce risk. Ensure all mailboxes have a good warmup health score (70+) before assigning them.
WarmySender tracks all key email engagement metrics:
Open Tracking:
A tiny invisible tracking pixel (1x1 PNG) is inserted into each email
When the recipient opens the email and loads images, the pixel fires and records an open event
First-open and repeat-open events are deduplicated for counter accuracy
Tracking tokens are signed with HMAC and expire after 90 days
Click Tracking:
All links in your email body are automatically wrapped with tracking redirects
When a recipient clicks a link, the click is recorded before redirecting to the original URL
Mailto: links, tel: links, and unsubscribe links are excluded from wrapping
Click events are deduplicated per prospect per campaign step
Reply Tracking:
Replies are detected via IMAP inbox sync — WarmySender scans your inbox for incoming messages
Replies are matched to active campaign enrollments
When a reply is detected, the prospect is automatically marked as 'replied'
If 'Stop on Reply' is enabled (default), the prospect is removed from further follow-ups
Cross-channel: email replies also stop LinkedIn campaign sequences
Bounce Detection:
Bounced emails are classified automatically
Important: Gmail 550-5.4.5 errors are classified as rate limits, not bounces — this prevents false campaign cooldowns
Unsubscribe Handling:
An unsubscribe link is added to your email footer
RFC 2369 and RFC 8058 compliant List-Unsubscribe headers are included
When a prospect unsubscribes, they are added to your suppression list and stopped from all campaigns
Custom Tracking Domains: Set up a custom CNAME tracking domain (e.g., track.yourdomain.com) from Settings > Tracking Domains for better deliverability. See the 'Tracking Domains' guide below.
WarmySender supports inserting images into your campaign emails using the Insert Image button in the email editor toolbar.
How to Insert an Image: 1. In the campaign email editor, click the Image icon (mountain/sun icon) in the toolbar. 2. Paste the URL of your image (must be a publicly accessible HTTPS URL). 3. Optionally add alt text (recommended for accessibility and email clients that block images). 4. Optionally set a width (e.g. 600 for full-width, 300 for half-width). 5. Click 'Insert Image' — the image appears inline in your email.
You can also insert images in code view by typing an <img> tag directly, for example: <img src="https://yoursite.com/image.png" alt="Description" width="600" />
Where to Host Your Images: Images must be hosted on a publicly accessible URL. You do not upload images to WarmySender — instead, host them on your own website, a CDN, or a free image hosting service: • Your company website or CDN (best option for brand consistency and reliability) • Google Drive (set sharing to 'Anyone with the link', then use the direct link) • imgbb.com (free, no account required) • Imgur (free for public images) • Any web server that serves images over HTTPS
Image Best Practices for Cold Email:
Keep images under 100KB — large images slow loading and may trigger spam filters.
Use HTTPS URLs — many email clients block HTTP images or show security warnings.
Maximum width: 600px — email clients render at 600-640px max width. Use width="600" for full-width images.
Use JPEG for photos, PNG for logos/graphics with transparency.
Avoid WebP — Outlook desktop does not support it.
Always add alt text — many email clients block images by default. Alt text shows when images are blocked.
Avoid GIFs in cold outreach — they increase email size and can hurt deliverability.
Deliverability Considerations:
Maintain an 80/20 text-to-image ratio — emails that are mostly images trigger spam filters.
Avoid images in the first email of a cold sequence — text-only first emails perform best for deliverability.
Limit to 1-2 images per email — each image is an external resource request that spam filters track.
Never send image-only emails — always include substantial text content alongside images.
A small logo in your email signature is generally safe and does not significantly impact deliverability.
Common Use Cases:
Company logo in email signature
Product screenshots in follow-up emails
Infographics or charts (after initial engagement)
Banner images for event invitations
Note: WarmySender does not support file attachments (PDFs, documents, etc.) in campaign emails. See the 'Email Attachments in Campaigns' guide for alternatives.
WarmySender does not support file attachments in campaign emails. This is an intentional design decision based on email deliverability best practices.
Why No Attachments:
Attachments dramatically increase the chance of your email landing in spam or being blocked entirely. Most spam filters flag emails with attachments from unknown senders.
File size increases email load time and can trigger rate limits from email providers.
Attachments are one of the top spam signals for Gmail, Outlook, and other major providers.
For cold outreach, attachments reduce open rates because recipients are wary of files from unknown senders.
Recommended Alternatives:
Link to a hosted file — Upload your PDF, brochure, or document to Google Drive, Dropbox, or your website, and include the link in your email. This is the safest approach.
Use a landing page — Create a simple landing page with your content and link to it. This also lets you track who visits.
Include key information in the email body — Instead of attaching a proposal or one-pager, include the most important points directly in your email text.
Follow up with attachments after a reply — Once a prospect replies and you have a relationship established, you can attach files in your direct reply from the Unified Inbox or your email client.
Best Practice: Treat your first cold email as a conversation starter, not a presentation. Save the detailed materials for after you have the prospect's attention and permission.
Note: If you want to add inline images (logos, screenshots, banners) to your emails, WarmySender does support this — see the 'Images in Campaign Emails' guide for details.
WarmySender allows you to set a unique email signature for each mailbox and insert it into your campaign emails using the {{signature}} merge tag.
Setting Up Your Signature: Each mailbox has its own signature, configured in the mailbox settings dialog under the Signature tab. Go to Email Infrastructure > Mailboxes, click the three-dot menu (⋮) on any mailbox, select "View Details", and go to the Signature tab. Signatures support both plain text and HTML, so you can include formatted text, links, or simple styling.
Using {{signature}} in Campaign Emails: In the campaign editor, insert the {{signature}} variable from the variable picker (or type it manually). When the email is sent, {{signature}} is replaced with the signature stored on the sending mailbox. If a campaign rotates across multiple mailboxes, each recipient automatically gets the correct signature for whichever mailbox sends their email.
Different Signatures per Mailbox: Since signatures are stored per-mailbox, you can have a different signature for each mailbox without creating separate campaigns. Simply set each mailbox's signature in its Signature tab, then use {{signature}} in your template — the system handles the rest.
Signature Best Practices:
Keep signatures short — 3-5 lines maximum for cold outreach.
Include your name, title, company, and one contact method (phone or LinkedIn).
Avoid images in signatures for cold outreach — they can trigger spam filters and increase email size.
Avoid large HTML signatures with logos and social icons in initial outreach.
You can also use sender merge tags ({{sender_name}}, {{sender_company}}) alongside or instead of {{signature}} for automatic personalization.
Test your signature renders correctly by using the 'Send Test' feature in the campaign editor.
Note: Signatures are not automatically appended — you must include {{signature}} in your email template body where you want the signature to appear.
Better targeting leads to higher reply rates. Here is how to segment your audience effectively.
Why Segment? • Personalized messaging for each segment increases reply rates by 2-3x. • Different roles need different value propositions (CEO vs. VP Sales vs. Manager). • Industry-specific pain points resonate more than generic pitches.
Segmentation Strategies:
By Role/Seniority:
C-Suite (CEO, CTO, CFO) — Focus on business outcomes, ROI, strategic value. Keep emails very short.
VP/Director — Focus on departmental impact, team efficiency, competitive advantage.
Manager — Focus on day-to-day pain points, ease of use, time savings.
By Industry:
Create industry-specific email templates referencing common challenges.
Use industry merge tags: 'In the {{industry}} space, we have seen...'
Revive cold prospects who did not respond to your initial campaign.
When to Re-engage:
30-60 days after your initial campaign completed with no reply.
After a significant product update or new feature launch.
When you have new social proof (case study, testimonial) relevant to their industry.
Around business milestones (new quarter, budget season, industry events).
Re-engagement Strategy:
Filter your prospect list to contacts who were 'contacted' but never 'replied'.
Create a NEW campaign (do not re-enroll in the old one).
Use a fresh angle — different subject line, different value proposition.
Reference the previous outreach: 'I reached out a few weeks ago about...' (honesty works).
Keep it shorter than your original sequence — 2-3 steps maximum.
Effective Re-engagement Templates:
The 'New Development' Email: 'Hi {{firstName}}, I reached out last month about [topic]. Since then, we have [new development/case study/feature]. Thought it might be relevant to {{company}} now.'
The 'Quick Question' Email: 'Hi {{firstName}}, is [problem area] still a priority for {{company}} this quarter? Happy to share how we are helping [similar companies] with it.'
The 'Breakup' Email: 'Hi {{firstName}}, I have reached out a couple of times and have not heard back. I completely understand if the timing is not right. Should I check back next quarter, or is this not relevant?'
Best Practices:
Wait at least 30 days between campaigns to the same prospect.
Change your approach — if the first campaign was problem-focused, try a case-study approach.
Use a different mailbox or at least a different subject line pattern.
Respect the per-prospect cooldown settings.
Remove prospects who bounced, unsubscribed, or were marked DNC from re-engagement lists.
Track re-engagement reply rates separately to measure what revival approaches work best.
Send fully unique, pre-written emails to each prospect — where every part (subject, opening line, body, CTA) is a variable pulled from your CSV.
Overview: This approach is ideal when you have already crafted unique emails for each prospect using AI tools, manual research, or copywriting. Instead of writing one template with a few merge tags, every element of the email is a custom field. WarmySender sends each prospect their own fully personalized message.
Step 1: Prepare Your CSV Add columns for every part of the email using the custom: prefix:
email,firstName,company,custom:subject_line,custom:first_line,custom:second_paragraph,custom:cta john@acme.com,John,Acme Corp,Quick question about Acme's Q1 growth,I saw your talk at SaaStr...,We help companies like Acme reduce churn by 30%...,Would you be open to a 15-min call next week? jane@globex.io,Jane,Globex,Loved your recent blog post,Your article on remote hiring resonated...,We built a tool that cuts hiring time by 40%...,Could I send you a quick demo video?
Key rules for CSV headers:
Prefix custom columns with custom: (e.g., custom:subject_line).
Field names are sanitized: lowercased, spaces/special chars become underscores, max 30 characters.
Use only alphanumeric characters and underscores after the prefix.
Step 2: Import Prospects 1) Go to your campaign > Prospects > Import CSV. 2) Upload your file. Built-in columns (email, firstName, company) auto-map. 3) Custom columns appear as 'Custom: subject_line', 'Custom: first_line', etc. 4) Confirm the mapping and import.
Step 3: Create Your Campaign In the email editor, use variables for every part:
Subject line: Click the subject field, then use the Variable Picker (the { } button in the toolbar) to insert {{custom.subject_line}}.
Body example: {{custom.first_line}}
{{custom.second_paragraph}}
{{custom.cta}}
Best regards, {{sender_name}}
Both {{custom.field_name}} and {{field_name}} syntax work, as long as the name does not conflict with a built-in field.
Step 4: Add Fallback Values Protect against missing data with fallback syntax: • Subject: {{custom.subject_line | default: 'Quick question for you'}} • Body: {{custom.first_line | default: 'I came across your company and was impressed by your work.'}} This ensures every prospect gets a coherent email even if a custom field is blank.
Tips and Best Practices:
Test with a small batch (5–10 prospects) first to verify variables resolve correctly.
Use the Preview feature to check each prospect's rendered email before launching.
Custom fields appear in the Variable Picker under the 'Custom Fields' group.
Combine with spintax for additional variation: {Hi|Hello} {{firstName}}, {{custom.first_line}}
You can have as many custom columns as you need — there is no limit on the number of fields.
Common Mistakes to Avoid:
Forgetting the custom: prefix in CSV headers — without it, unrecognized columns are skipped.
Using spaces in field names — use underscores instead (custom:first_line, not custom:first line).
Not adding fallback values — if even one prospect is missing a field, they get a blank in the email.
Exceeding 30 characters for field names — keep names short and descriptive.
Create and manage email campaigns programmatically using the WarmySender API.
Required Scope: campaigns:write (for campaign CRUD), enrollments:write (for enroll/unenroll) Create an API key with the needed scopes in Settings > API Keys.
Campaign Lifecycle via API:
Create a campaign (POST /api/v1/campaigns) — always created in draft status
Review and adjust settings (PATCH /api/v1/campaigns/:id)
Enroll prospects (POST /api/v1/campaigns/:id/enrollments) — accepts prospectIds, listIds, or emails
Start the campaign (POST /api/v1/campaigns/:id/start)
Monitor progress (GET /api/v1/campaigns/:id)
Pause if needed (POST /api/v1/campaigns/:id/pause)
Unenroll prospects (DELETE /api/v1/campaigns/:id/enrollments) — remove specific prospects from a running campaign
Creating Prospects with LinkedIn URL: POST /api/v1/prospects supports a linkedinUrl field for multichannel outreach: • email (required), firstName, lastName, company, role, phone, linkedinUrl, customFields (object) • The linkedinUrl field accepts any valid LinkedIn profile URL • Deduplication is by email — if the email exists, the existing prospect is returned
Creating a Campaign: POST /api/v1/campaigns requires: • name — Campaign name (required) • steps — Array of email steps with subject, bodyHtml, and stepIndex (at least 1 required) • mailboxIds — Array of connected mailbox IDs to send from (at least 1 required) • Optional: prospectIds, dailySendLimit, timezone, scheduleDays, trackOpens, trackClicks, stopOnReply, stopOnBounce, startDate, endDate
Key Rules:
Campaigns are always created in draft status — you must explicitly start them.
Step 0 always has delayDays=0 (sends immediately). Other steps default to 1 day delay.
All mailboxes must be connected and have sending enabled.
Prospects with bounced, unsubscribed, or suppressed status are automatically marked as suppressed in the enrollment.
The API supports email, linkedin, and multichannel campaigns via the channel field (defaults to email).
Updating a Campaign: PATCH /api/v1/campaigns/:id — only works on draft or paused campaigns. You can update name, dailySendLimit, sendingWindowStart/End, scheduleDays, tracking settings, and dates.
Starting a Campaign: POST /api/v1/campaigns/:id/start checks: • Campaign has at least one step and one mailbox. • End date (if set) has not passed. • Your subscription is active. • If startDate is in the future, campaign is set to 'scheduled' instead of 'running'.
Pausing a Campaign: POST /api/v1/campaigns/:id/pause — works on running or scheduled campaigns. Sets pausedReason to 'api'.
Enrolling Prospects: POST /api/v1/campaigns/:id/enrollments — add prospects to a campaign. • Request body: { prospectIds?: string[], listIds?: string[], emails?: string[] } — pass at least one. • prospectIds: directly enroll specific prospects by ID. • listIds: enroll all prospects from one or more prospect lists. • emails: find and enroll prospects by email address. • You can combine all three in a single request. • Requires enrollments:write scope.
Unenrolling Prospects: DELETE /api/v1/campaigns/:id/enrollments — remove prospects from a campaign. • Request body: { prospectIds?: string[], emails?: string[] } — pass one or both. • Response: { data: { unenrolledCount: number, totalProcessed: number } } • Prospects not currently enrolled are skipped (counted in totalProcessed but not unenrolledCount). • Use case: unenroll when a prospect replies on another channel (e.g., WhatsApp, LinkedIn) to avoid duplicate outreach.
Idempotency: The create endpoint supports the Idempotency-Key header for safe retries. Use a unique key per creation request.
Full API Reference: warmysender.com/docs/integrations
Common errors when using the Campaign API and how to resolve them.
400 validation_error — Invalid Request Body Cause: Missing required fields or invalid values. Common issues: • 'name' is required and must be 1-200 characters • 'steps' array must have at least 1 step and at most 50 • 'mailboxIds' array must have at least 1 mailbox ID • 'dailySendLimit' must be between 1 and 10,000 • Each step must have a unique 'stepIndex' (duplicates are rejected) • 'endDate' must be in the future and after 'startDate' Fix: Check the error response 'details' field for specific validation failures.
400 unusable_mailboxes — Mailbox Not Usable Cause: One or more mailboxes are disconnected or have sending disabled. Fix: Go to Settings > Mailboxes and reconnect the mailbox. Ensure 'Sending Enabled' is turned on.
400 invalid_status — Wrong Campaign Status Cause: Attempting an action not allowed for the current status. • Cannot update a running campaign — pause it first (POST /:id/pause) • Cannot start a completed or errored campaign • Cannot pause a draft or already-paused campaign Fix: Check the campaign status with GET /api/v1/campaigns/:id first.
400 end_date_expired — End Date Has Passed Cause: Trying to start a campaign whose end date is already in the past. Fix: Update the end date (PATCH) or set it to null to remove it.
403 insufficient_scope — Missing API Key Scope Cause: Your API key does not have the required scope. • Creating/updating/starting/pausing: requires campaigns:write • Reading campaign data: requires campaigns:read • Enrolling prospects: requires enrollments:write Fix: Create a new API key with the needed scopes in Settings > API Keys.
403 subscription_blocked — Subscription Issue Cause: Your subscription is inactive, past due, or expired. Fix: Visit Settings > Billing to update your payment method or renew.
404 not_found — Campaign Not Found Cause: The campaign ID does not exist, belongs to a different workspace, or was deleted. Fix: Verify the campaign ID. Use GET /api/v1/campaigns to list all campaigns.
409 conflict — Duplicate Data Cause: Duplicate prospect enrollment (same prospect already enrolled in this campaign). Fix: Check existing enrollments before enrolling. Use the Idempotency-Key header for safe retries.
429 Too Many Requests — Rate Limited Cause: Exceeded 60 requests per minute. Fix: Implement exponential backoff. Wait and retry after the rate limit window resets.
Idempotency Tips:
Use the Idempotency-Key header on POST /api/v1/campaigns for safe retries
Each unique key caches the response for 24 hours
If your request times out, retry with the same key — you will get the cached result, not a duplicate campaign
Generate keys using UUIDs (e.g., crypto.randomUUID())
Sometimes campaign prospects are marked as 'Failed' with the error 'stuck in processing loop after 3+ recovery cycles'. This guide explains what this means and how to prevent it.
What Is a Stuck Processing Loop? When a campaign sends an email, it creates a 'send job' that goes through these states: pending → processing → completed. If a job gets stuck in the 'processing' state for more than 10 minutes (for example, because the sending mailbox hit its daily limit or was temporarily unavailable), the system's recovery watchdog detects it and retries.
The 3-Strike Rule Each stuck job is given up to 3 recovery attempts: • Attempt 1: Job reset to pending, retried at next available slot • Attempt 2: Same process — reset and retry • Attempt 3: If the job gets stuck again, the system permanently fails the prospect to prevent an infinite retry loop
The prospect status changes to 'Failed' with the message: 'Failed: stuck in processing loop after 3+ recovery cycles'
Common Causes 1) Daily mailbox limit exhausted — If your campaign has many prospects but only one mailbox with a low daily limit (e.g., 30 emails/day), the system cannot process all scheduled jobs within the limit. Jobs queue up and repeatedly miss the sending window.
Outside sending window — Jobs scheduled near the end of your sending window may not get processed in time. They expire and get rescheduled, burning recovery attempts.
Mailbox temporarily disconnected — If your mailbox has intermittent connection issues during the processing window.
Too many campaigns sharing one mailbox — Multiple campaigns competing for the same mailbox's daily capacity.
How to Prevent This • Add more mailboxes — Distribute sending across 3-5 mailboxes per campaign. This provides more daily capacity and reduces competition for send slots. • Reduce daily sending volume — If you have 500+ prospects and only 30 sends/day capacity, pace your campaign appropriately. • Use mailbox rotation — Assign multiple mailboxes with round-robin rotation so if one hits its limit, others can take over. • Check sending windows — Make sure your sending window is wide enough to process all daily sends. • Upgrade your plan — Higher plans allow more daily sends and more mailboxes.
What to Do About Failed Prospects Failed prospects are not lost — they remain in your campaign and can be re-enrolled: 1) Go to your Campaign detail page and filter prospects by 'Failed' status. 2) Review the failed prospects to confirm they have valid email addresses. 3) You can create a new campaign with the same prospects, or reset their status if the system allows. 4) Before re-enrolling, ensure you have enough mailbox capacity by adding more mailboxes or reducing other campaign volumes.
Monitoring Check your campaign's event log for 'error' events with reason 'stuck_processing_loop'. If you see many of these, it is a clear signal that your sending capacity needs to be increased for the campaign volume.
The stat box at the top of every campaign detail page (Sent, Opens, Clicks, Replies, Bounces, Open Rate, Click Rate, Reply Rate) is often misunderstood. Here is exactly what it shows.
What the Overview Stat Box Shows The overview stat box displays ALL-TIME cumulative totals for the campaign since it was created. Every email ever sent, every open ever tracked, every click ever recorded, and every reply ever received is counted — from day one of the campaign through right now.
This is NOT a daily, 12-hour, or rolling-window view. It is the complete lifetime of the campaign in a single glance.
Real-Time Updates The numbers refresh automatically every 30 seconds while you have the page open. You do not need to reload the page — opens, clicks, and replies that come in are reflected almost immediately in the stat box.
Common Misconception: 12-Hour or Daily View Some users assume the stat box only shows recent activity (for example, 'sent in the last 12 hours' or 'today's stats'). That is incorrect — it is all-time, cumulative, since campaign creation. If your campaign has been running for 3 weeks, the stat box reflects the entire 3 weeks, not just today.
When You Need a Time Window If you want time-windowed views — for example, 'how did my campaign perform over the last 7, 14, 30, or 90 days?' — use the Analytics page instead. Analytics supports date range filters and gives you day-by-day trend charts, which is the right tool for performance analysis over specific periods.
Quick Rule of Thumb • Campaign overview stat box → lifetime totals, updated every 30 seconds • Analytics page → time-windowed views and trend charts
The two views are designed to complement each other. Use the overview for a running tally of your campaign, and use Analytics when you need to slice performance by date.
Each campaign has a 'Minutes Between Sends' setting that controls the minimum interval between consecutive sends from that campaign. When the same mailbox is used by multiple campaigns (or by warmup at the same time), WarmySender enforces a per-mailbox global pacer on top of the per-campaign setting to protect your account.
How the Per-Mailbox Pacer Works The pacer is a global throttle that applies to every mailbox. It tracks the last send time from that mailbox — across all campaigns AND warmup — and blocks any new send until the minimum interval has elapsed. This prevents back-to-back sends from any combination of campaigns and warmup activity.
The Floor Is the Longest Interval If Campaign A has Minutes Between Sends = 5 and Campaign B (using the same mailbox) has Minutes Between Sends = 15, the effective floor for that mailbox is 15 minutes. The longest minimum interval among all campaigns sharing the mailbox wins. This is intentional — the system respects the most conservative setting to keep your mailbox safe.
Warmup Counts Toward the Same Pacer Warmup sends are not exempt. If warmup just sent an email from your mailbox, the next campaign send is delayed until the Minutes Between Sends interval has elapsed — and vice versa. Your mailbox will not send a warmup email and a campaign email within the same interval window. This ensures the mailbox always looks like a human is at the keyboard, not a bot blasting messages.
Why This Exists: Account Safety and Deliverability Email providers (Gmail, Outlook, Yahoo) flag bursts of rapid-fire sends as bot-like behavior. A mailbox that sends 5 emails in 30 seconds is a huge red flag — it looks like a compromised account or a spammer. The pacer makes sure every send looks natural and spaced out, protecting your sender reputation across all of your outbound activity.
What You Might Notice • A campaign may appear to send slower than its 'Minutes Between Sends' setting suggests — that means another campaign or warmup is sharing the mailbox and the longer interval is in effect. • Your effective throughput per mailbox is capped by the longest interval, not the shortest. • To increase throughput safely, add more mailboxes to the campaign rather than lowering the interval.
Best Practice • Use consistent Minutes Between Sends settings across campaigns that share mailboxes, so you know what to expect. • If you need higher volume, scale horizontally by adding mailboxes — do not lower the interval below safe thresholds. • Keep warmup running alongside campaigns — the pacer will coordinate both safely.
WarmySender's LinkedIn add-on automates your LinkedIn outreach:
Ensure You Have a Paid Plan — LinkedIn requires an active paid subscription (any paid plan). If you're on the free tier, upgrade first from the Billing page.
Purchase LinkedIn Seats — Go to Billing and purchase LinkedIn seats at $9/month per seat. Each seat allows one connected LinkedIn account.
Connect Your Account — Go to LinkedIn > Accounts and connect your LinkedIn account. The system supports cookie-based auth, credentials login, or OAuth. If 2FA is required, you'll be prompted to enter your verification code (valid for 10 minutes).
Create an Audience — Use Find LinkedIn Prospects to search LinkedIn directly, or import from CSV. Save selected profiles to an Audience.
5) Create a LinkedIn Campaign — Go to LinkedIn > Campaigns and build your sequence:
Each step has configurable delays and personalization
Connection request notes are limited to 300 characters
Direct messages can be up to 8,000 characters
Set Daily Limits — The system enforces safe limits based on your account type and age. Free accounts: up to 150 invites/week at full ramp. Premium/Sales Navigator: up to 200 invites/week.
Monitor Performance — Track acceptance rates, reply rates, and engagement from LinkedIn Analytics.
Manage Conversations — View and reply to all LinkedIn conversations from LinkedIn > Conversations. Messages sync automatically every 30 seconds.
Safety: The system uses intelligent rate limiting with a 4-week ramp-up period, circuit breakers, and exponential backoff to protect your LinkedIn account from restrictions.
Detailed guide for connecting your LinkedIn account:
Prerequisites:
Active paid subscription (any paid plan)
Active LinkedIn seat ($9/month from Billing page)
LinkedIn account in good standing (no current restrictions)
Connection Steps:
Go to LinkedIn > Accounts and click 'Connect Account'
Choose your connection method — credentials, cookie-based, or OAuth
Enter your LinkedIn login details
If 2FA is enabled: you'll be prompted for a verification code. Enter it within 10 minutes.
Wait for the connection to complete — your account will show 'Connected' status
Account Types Detected:
Free — Standard LinkedIn (150 invites/week cap)
Premium — LinkedIn Premium (200 invites/week cap)
Sales Navigator — Extended search and InMail access
Recruiter — Recruiter-specific features and limits
Strategy Assignment: The system assigns a safety strategy based on your account history: • New Account — 6-week ramp-up, most conservative limits • Established — 4-week ramp-up, moderate limits • Veteran — 2-week ramp-up, higher limits • Recovery — 8-week ramp-up, applied after account restrictions
Proxy Support: Each account gets a dedicated fixed IP — your traffic never routes through a shared server. Configure during Step 2 of connection: • Auto — System-assigned proxy geo-located near your real IP (default, recommended) • Country — Select a specific country from 40+ available locations • Custom — Provide your own proxy URL (HTTP, HTTPS, or SOCKS5 with optional auth) For full details, supported countries, and custom proxy format, see the 'LinkedIn Proxy & IP Security' guide in this section.
Reconnection: If your LinkedIn session expires, the account status changes to 'Needs Verification'. All active campaigns are auto-paused. After reconnecting, campaigns automatically resume.
Manage all LinkedIn conversations from LinkedIn > Conversations:
Conversation List:
View all LinkedIn message threads from your connected accounts
Filter by: All / Unread / Replied, and by specific LinkedIn account
Search conversations by text
Campaign tracking badges show which conversations came from campaigns
Conversations auto-refresh every 30 seconds
Message Thread:
View the full conversation history with timestamps and delivery status (sent, delivered, read)
See prospect profile info alongside the conversation
Replying:
Reply directly from WarmySender without switching to LinkedIn
Use quick-insert templates for common responses
Message limit: 8,000 characters
Select which LinkedIn account to send from (if you have multiple)
Campaign Integration:
When a prospect replies to your LinkedIn campaign message, they are marked as 'replied' and removed from further automated follow-ups in that campaign
The conversation thread shows which campaign step triggered the initial message
The Unified Inbox also has a LinkedIn tab showing all LinkedIn conversations alongside your email replies for a complete view of all prospect interactions.
Ramp-Up Period: Limits start low and increase over 4 weeks. Actual daily limits ramp gradually per account type — for example, a Free account ramps from ~15 invites/day in week 1 to ~40/day at full ramp. The system calculates your exact daily limits based on your account age.
Strategy-Based Limits (additional layer):
New Account (6 weeks): max 150 invites/week, 75 messages/day
Established (4 weeks): max 175 invites/week, 85 messages/day
Veteran (2 weeks): max 200 invites/week, 100 messages/day
Recovery (8 weeks): max 100 invites/week, 50 messages/day
The system takes the MINIMUM of account-type and strategy limits
Safety Mechanisms:
If API calls fail repeatedly, LinkedIn operations are automatically paused to prevent account restrictions
Errors trigger increasing delays between retry attempts
The system monitors for LinkedIn restriction signals and pauses proactively
Account Restriction Handling:
If LinkedIn restricts your account, all campaigns are auto-paused immediately
After 2+ restrictions, the system switches to Recovery strategy (most conservative)
Campaigns do NOT auto-resume after restrictions — you must manually verify and resume
If your LinkedIn campaign appears to send fewer invites or messages than you expected — or seems to stop sending after a few — there is almost always a safe and intentional reason. WarmySender's #1 priority on LinkedIn is your account's survival. A banned LinkedIn account is unrecoverable, so the platform errs heavily on the side of caution.
Reason 1: LinkedIn's per-account limits (the hardest constraint) LinkedIn enforces strict per-account limits regardless of which automation tool you use. WarmySender respects these limits because exceeding them is the fastest way to get an account restricted or banned.
Free LinkedIn account: ~150 invites per week (no note attached). Some free accounts that send invite notes have been observed at as low as ~5 invites per month before LinkedIn temporarily blocks further invites. Free accounts hit weekly caps fastest — if you are running an aggressive invite campaign on a free account, expect a low ceiling.
LinkedIn Premium: ~80-100 invites per day (~200/week typical).
LinkedIn Sales Navigator: ~80-100 invites per day (~200/week typical).
LinkedIn Recruiter: ~200/week typical, plus separate InMail credit pool.
These are LinkedIn's safety thresholds, not WarmySender's. If your account hits the weekly cap on Tuesday, no third-party tool can make LinkedIn accept more invites until the cap rolls over. WarmySender will detect this, mark the prospect for retry 4-8 hours later, and try again. The prospect is never silently dropped.
Reason 2: The 4-6 week safety ramp on every new account A new LinkedIn account connected to WarmySender does NOT immediately send at full speed. Every new account starts in a conservative ramp window:
Week 1: ~10-15 invites/day (around 70-105/week)
Week 2: ~20 invites/day
Week 3: ~30 invites/day
Week 4+: full ramp (subject to your account-type cap above)
This ramp matches LinkedIn's safe expectations for a new automation pattern. Older accounts with established history (used WarmySender for 1+ months without restriction) move faster. Accounts that have ever been restricted move slower (Recovery strategy: 8-week ramp at half speed).
Reason 3: We honor 'try again later' responses correctly When LinkedIn responds 'cannot resend yet — temporary provider limit' to an invite attempt, that is LinkedIn telling us to back off for a few hours. Our system's response: reschedule that prospect's invite for 4 to 8 hours later (with a small random offset to avoid bursting), and DO NOT advance the prospect past the invite step. The next scheduler tick will retry. Because of this behavior, you may see a campaign sit at a low daily count for a day or two, then rebound the next day once the per-account window has rolled over.
Reason 4: Your campaign's own schedule Each campaign has 'schedule_days' (which days of the week sending is allowed) and a sending window (which hours, in your campaign's timezone). Common patterns: weekdays only, Mon/Tue/Wed only, Tue-Thu. If today isn't a scheduled day, your campaign correctly sits idle. If you set Mon/Tue/Wed and it is now Thursday, you will see 0 sends — that's by your configuration. Edit schedule from campaign settings.
Reason 5: We never bulk-replay missed sends after an outage If a fix or reconnect happens after a quiet period, WarmySender does NOT 'catch up' by sending a burst of held-back invites. Bursting after a gap is exactly the pattern LinkedIn uses to detect automation. Throughput catches up naturally over the next 1-2 weeks of normal scheduling.
What to check first if you think your campaign is too slow:
1. Go to LinkedIn → Accounts and check your account type pill (Free / Premium / Sales Navigator / Recruiter). Free accounts have the lowest cap. 2. Check 'connected for X weeks' — if under 4 weeks, you are still in the safety ramp. 3. Open the campaign's analytics and look for skipped enrollments labeled 'rate limited' or 'cannot resend yet' — those are LinkedIn-side caps, not bugs. 4. Check schedule_days and sending window — make sure today and now is within them. 5. Check whether your account is shared across multiple campaigns. One account = one daily/weekly cap, split across all campaigns it powers. If you have 4 campaigns on one account, they are competing for the same 50 message-equivalent slots/day.
When to contact us: If your account is connected for more than 4 weeks, you are within schedule, you have weekly cap remaining, and you still see no sends for >24 hours, email hello@warmysender.com with the campaign name and your timezone. We will dig into the specific row.
For the LinkedIn limits we enforce against, see Unipile's full provider-limits doc: https://developer.unipile.com/docs/provider-limits-and-restrictions
From time to time we ship platform-level updates that improve sync speed, delivery reliability, and account-state guarantees. After certain rollouts, LinkedIn accounts connected to WarmySender need a quick re-authentication so the new platform components can pick up the session. If you see an amber 'Reconnect needed' banner at the top of LinkedIn → Accounts, this guide is for you.
Why reconnects sometimes happen after a platform update WarmySender connects to LinkedIn through Unipile, an authentication and orchestration partner. When we upgrade core components — for example, our queue runtime, our LinkedIn worker pool, or the way we register accounts on Unipile's side — accounts that were connected on the old infrastructure can become 'orphaned' relative to the new layer. Their actual LinkedIn session is fine; what's stale is the link between WarmySender and Unipile for that specific account. The fastest, safest fix is for you to re-trigger the auth handshake so a fresh, clean record is created on the new infrastructure. This is intentional — silently rebinding accounts in the background is exactly the pattern LinkedIn flags as suspicious. A brief, user-initiated reconnect keeps your account in great standing. We will only ever send you a reconnect email when the change is rolling out platform-wide; ad-hoc disconnects (LinkedIn-side session expiry, password change, 2FA reset) are covered in our separate 'Why does my LinkedIn account show as disconnected?' guide.
Who needs to reconnect Anyone whose LinkedIn account on the LinkedIn → Accounts page shows the amber 'Reconnect needed' alert. If the page is fully green for every account, no action is needed on your end. If even one account is amber, click Reconnect on that row to clear it. Multi-account workspaces should reconnect each affected account individually — it takes about 30 seconds per account.
How to reconnect (4 steps, ~30 seconds) 1) Open WarmySender and go to LinkedIn → Accounts in the sidebar. Affected accounts show an amber 'Reconnect needed' alert with a primary 'Reconnect Account' button. (Screenshot: an amber banner at the top of the page reading 'Reconnect needed — N LinkedIn account(s) require re-authentication' followed by per-row alerts on each affected account.) 2) Click 'Reconnect Account' on the row. You'll be routed to a hosted re-authentication page. No credentials are shared with WarmySender directly — Unipile handles the auth securely via LinkedIn's official OAuth-style handshake. 3) Confirm your LinkedIn login. If 2FA is enabled, enter the code. If LinkedIn shows a security challenge or CAPTCHA, complete it as you would any other LinkedIn login. The whole thing should take ~15-20 seconds. 4) Return to WarmySender. The status pill flips from amber 'disconnected' to green 'connected' within seconds. The aggregate banner at the top of the page disappears once every affected account is reconnected. (Screenshot: green 'Connected' status pill alongside the account row, and the amber top-of-page banner gone.)
What happens to my campaigns during reconnection The moment a LinkedIn account becomes disconnected, every campaign attached to it is auto-paused with reason 'account_disconnected' or 'linkedin_account_disconnected'. Each affected campaign shows a small hint on the campaign card and detail page: 'Will auto-resume after LinkedIn account reconnection.' Prospects keep their exact place in the sequence — nothing is dropped, nothing is reset, no step is skipped. As soon as you complete the reconnect, the platform's failure-rate window resets for that account and the next scheduler tick (within ~5 minutes) automatically resumes the paused campaigns. You do not need to manually click Resume on each one. Account safety always wins: even on resume, sends respect your daily / weekly LinkedIn caps, your sending window, and your active days — there is no burst catch-up of held-back invites.
If a campaign was paused for any OTHER reason at the same time (manual pause, high failure rate from before the disconnect, or a different downstream issue), it may still need a manual Resume from its settings page after reconnection. If you click Resume and it immediately re-pauses, contact support — that signals a stale failure window that needs manual reset.
FAQ Q: Will I lose my prospects or audiences? A: No. Reconnecting only refreshes the link between WarmySender and your LinkedIn session. Your prospects, audiences, conversations, campaign sequences, and historical metrics are all stored on our side and are untouched by the reconnect.
Q: Will my campaigns restart from the beginning? A: No. Campaigns resume from the exact step each prospect was on at the time of the disconnect, including any 'wait for acceptance' or 'wait N days' delays that were in flight. There is no reset and no re-enrollment.
Q: What if reconnect fails or the status doesn't update? A: Wait 30-60 seconds for Unipile's webhook to land, then click 'Sync Status' from the account's three-dot menu. If the status still shows disconnected after a manual sync, the auth flow may not have completed — close any in-progress reconnect tab and try the reconnect button again from a fresh browser tab. If it still fails after a second attempt, email hello@warmysender.com with your account email and we'll look at the specific row.
Q: How often do I need to reconnect? A: Rarely. Platform-update reconnects are infrequent — usually only after meaningful infrastructure rollouts. Ad-hoc reconnects are also rare and are typically driven by LinkedIn (password change, 2FA reset, idle session, IP region change). Accounts in good standing on Premium / Sales Navigator can go months without ever needing a reconnect.
Q: Is my LinkedIn account safe? Will this trigger a flag? A: Yes, your account is safe. The reconnect uses LinkedIn's official authentication flow via Unipile — the same secure handshake any approved tool uses. We never store your LinkedIn password, never bypass 2FA, and never reuse stale tokens. Reconnect after a platform update is a routine, low-stakes action that LinkedIn treats exactly like any other login from your normal IP/device.
Your LinkedIn account can show as disconnected for several reasons — most of them are LinkedIn requiring re-authentication for security, not a bug on our side. WarmySender pauses your campaigns automatically the moment we detect a disconnect, because sending while the account is in a half-authenticated state is exactly how LinkedIn detects automation and restricts accounts.
The Unipile account status lifecycle WarmySender uses Unipile as our LinkedIn integration partner. Unipile reports each connected account in one of these states:
OK / connected — Account is fully authenticated. Sends proceed normally.
CREDENTIALS — LinkedIn invalidated the session. You need to re-enter your password (and 2FA code if enabled). Most common reason for disconnects.
IN_APP_VALIDATION — LinkedIn is asking for additional verification (CAPTCHA, security challenge, suspicious activity check). You need to log into LinkedIn directly in a browser, complete the challenge, then reconnect through WarmySender.
MISSING — Internal tracking inconsistency (rare). Reconnect and try again.
When we detect any state other than OK / connected, your LinkedIn campaigns associated with that account are automatically paused.
Why LinkedIn forces re-authentication (not your fault) Common triggers, all initiated by LinkedIn for security:
Password change on LinkedIn
2FA reset or new device verification
Idle session expired (LinkedIn's session windows are not advertised but vary)
IP region change detected (e.g. you logged in from a different country, or your VPN/proxy IP rotated)
Suspicious activity flag (false positives happen, especially after a busy day)
LinkedIn rolled their auth tokens platform-wide (rare)
None of these are caused by WarmySender. The frequency depends on your LinkedIn account's history and how often you log in elsewhere. Some accounts go months without a disconnect; others need re-authentication every few weeks.
What WarmySender does automatically when an account disconnects
1. We detect the disconnect within minutes (Unipile webhook + periodic health check). 2. We immediately pause every campaign attached to that account, with pause reason 'account_disconnected'. 3. No further sends are attempted on that account until you reconnect. 4. Existing prospects in mid-sequence keep their place — nothing is lost. They wait at their current step. 5. If the disconnect persists for more than 24 hours, we email you a 'Your LinkedIn account [Name] disconnected — paused N campaigns' message with a one-click reconnect link.
How to reconnect
1. Go to Settings → LinkedIn Accounts (or LinkedIn → Accounts in the sidebar). 2. Find the disconnected account — it will show a red status pill and a 'Reconnect' button. 3. Click 'Reconnect'. You'll be redirected to a hosted authentication page (no password is shared with WarmySender). 4. Complete LinkedIn's verification: enter your password, 2FA code if requested, and resolve any CAPTCHA or in-app validation challenge. 5. Return to WarmySender. The account status flips back to 'connected' within seconds.
Do I need to manually unpause my campaigns? In most cases, no — campaigns paused with reason 'account_disconnected' resume automatically on the next scheduler tick after reconnection. The platform also resets the failure-rate window on every campaign attached to the just-reconnected account, so a backlog of dead-account-era errors won't immediately re-pause the campaign on resume.
However, if a campaign was paused for any OTHER reason at the same time (e.g. high failure rate from before the disconnect, manual pause, or a different downstream issue), it may still need manual resume from the campaign's settings. If you click Resume and the campaign immediately re-pauses, contact support — that signals a stale failure window that needs manual reset.
If your LinkedIn add-on seat was canceled If the disconnect happened because your LinkedIn add-on seat was canceled (not because LinkedIn force-logged you out), the reconnect flow routes you to Billing instead. Add a seat back, and the existing campaigns and audiences stay intact.
Why frequent disconnects can happen on free LinkedIn accounts Free LinkedIn accounts have stricter session policies than Premium / Sales Navigator. If you experience repeated disconnects on a free account, the long-term fix is upgrading to a paid LinkedIn tier — they get longer session windows, fewer security challenges, and higher per-account daily caps.
FAQ:
Q: My account shows 'connected' but campaigns are paused. Why? A: The disconnect probably resolved automatically (LinkedIn re-validated the session in the background) but the campaigns kept their previous pause reason from the disconnect window. Open the campaign and click Resume manually. If it re-pauses, contact support.
Q: Will my prospects be lost during a disconnect? A: No. Every prospect's position in the sequence is preserved. When the campaign resumes, prospects continue from exactly the step they were on, including any 'wait for acceptance' or 'wait N days' delays that were in flight.
Q: How long do I have to reconnect? A: Indefinitely — there's no deadline. But the longer you wait, the more pent-up backlog builds in your campaigns. After reconnecting, the platform respects per-account daily caps, so a long disconnect won't be 'caught up' in a burst.
Q: Can I prevent disconnects? A: Mostly no — they're triggered by LinkedIn's security, not by us. Things that help: don't log into LinkedIn from new devices/IPs while your WarmySender account is active, don't change your LinkedIn password during a campaign, and consider upgrading from a free LinkedIn account to Premium if you're hit with frequent disconnects.
If your LinkedIn account dashboard shows 'Reconnect needed', 'Linking — finishing connection', or 'Linking — taking longer than expected', this guide explains what each badge means, why it happens, and how to fix it in under a minute. The platform always tells the truth about current state — the pill never lies about the row's actual health.
The short version
LinkedIn rotates the session tokens that authenticate your account roughly every 30 days, plus immediately on any suspicious-login signal (new device or IP, password change, 2FA reset, security challenge). When the token expires, our integration partner Unipile reports the account as needing fresh credentials — and we surface that to you as 'Reconnect needed'. A 1-hour orphan watcher also detects accounts that finished OAuth on Unipile's side but never linked back to our database (a rare race condition), so even if a row is stuck in 'Linking…', it self-heals within an hour.
What each status pill means
Connected · last activity Xh ago (green dot) — The account is fully authenticated and we recently saw a successful Unipile call (sync, send, or health check). 'Last activity' is derived from the most recent `last_sync_at` timestamp on the row. If that timestamp is older than 24 hours and you have campaigns enrolled, contact support.
Linking — finishing connection (blue dot, spinner) — Your OAuth callback completed in the last 5 minutes and Unipile is finalising the handshake. Most of these resolve in under 60 seconds. No action is needed; just wait.
Linking — taking longer than expected (amber dot) — The 'connecting' state has lasted more than 5 minutes. This is rare. The orphan watcher will auto-relink within 60 minutes if Unipile completed on its side. Try clicking 'Reconnect' from the account's menu, or contact support if it persists past 30 minutes.
Reconnect needed (amber dot) — LinkedIn invalidated the session token. You need to click 'Reconnect Account' and complete a fresh login (password + 2FA if enabled). Campaigns auto-pause until you reconnect; they auto-resume within 5 minutes after.
Verification Required (yellow dot) — LinkedIn is asking for an in-app challenge (CAPTCHA, security question, suspicious-activity check). Click 'Reconnect' and complete the challenge as you would any normal LinkedIn login.
Restricted (red dot) — LinkedIn has restricted the account on their side. Most restrictions auto-lift in 24-48 hours. Reconnect after the restriction clears.
Disconnected (gray dot) — The account was disconnected by you or by the platform. Click 'Reconnect' to restore it.
Why LinkedIn forces re-authentication (the real reason)
LinkedIn issues every authenticated session a short-lived token. That token is what proves to LinkedIn each action (sending an invite, fetching a profile, posting a comment) is coming from you, not a bot. LinkedIn rotates these tokens for security — the same way your bank logs you out periodically. When the token expires or is invalidated, Unipile reports the account's source status as 'CREDENTIALS', meaning the LinkedIn-side credential check failed and a fresh login is required. (See https://developer.unipile.com/docs/getting-started for technical detail.)
Common triggers, all initiated by LinkedIn — not by WarmySender:
Routine ~30-day rotation (most common; happens to every account, even healthy ones)
Password change on LinkedIn
2FA reset or new device verification
IP region change (logged in from a different country, or your VPN/proxy IP rotated)
LinkedIn security challenge or CAPTCHA
Idle session — the account was not actively used for a while
Premium and Sales Navigator accounts get longer windows than free accounts, but every account eventually rotates.
The auto-relink guarantee (1-hour orphan watcher)
If an account ever gets stuck in 'Linking — finishing connection' for more than 5 minutes, the platform's orphan watcher (introduced 2026-04-30 alongside the Unipile-link integrity fixes) detects it and self-heals automatically. The watcher runs hourly and looks for accounts that finished the OAuth handshake on Unipile's side but never received the linking callback on our side (a rare network race). When it finds one, it links the row back to the live Unipile account, flips status to 'connected', writes an audit row, and resumes any paused campaigns.
In practice this means: even if you see 'Linking — taking longer than expected' right now, you do not need to do anything. Wait up to 60 minutes and the watcher will fix it. If it still hasn't relinked after an hour, then click Reconnect or contact support.
How to reconnect (4 steps, ~30 seconds)
1. Open WarmySender and click LinkedIn → Accounts in the sidebar (or click the link in the reconnect email). 2. Find the affected account showing the amber 'Reconnect needed' badge. Click the menu (⋮) on that row and choose 'Reconnect'. 3. You'll be routed to a hosted re-authentication page. Enter your LinkedIn email and password. If 2FA is enabled, enter the code. If LinkedIn shows a security challenge or CAPTCHA, complete it as you would any normal LinkedIn login. WarmySender never sees your password — Unipile handles the secure handshake with LinkedIn directly. 4. Return to WarmySender. The pill flips to green 'Connected · last activity moments ago' within seconds. Campaigns auto-resume within 5 minutes.
What happens after you reconnect
The self-heal sweeper runs every 5 minutes and automatically resumes any campaign paused with reason 'linkedin_account_disconnected' once the underlying account is back to 'connected'. You do not need to manually click Resume on each campaign. The platform also clears the failure-rate window so dead-account-era errors don't immediately re-pause anything. Account safety still wins on resume — sends respect your daily and weekly LinkedIn caps, sending window, ramp schedule, and active days. There is no burst catch-up of held-back invites, ever.
FAQ
Q: Why did my account disconnect even though it's in good standing? A: LinkedIn rotates session tokens for security every ~30 days, regardless of account standing. Even healthy, paid Sales Navigator accounts that have never been restricted hit the rotation. Premium and Sales Navigator typically rotate less frequently than free accounts, but no account is exempt.
Q: My pill shows 'Linking — taking longer than expected'. Did something break? A: Probably not. The OAuth callback hasn't fully landed yet on our side. The 1-hour orphan watcher self-heals these. If it's been more than an hour, click Reconnect from the account menu or contact support.
Q: Why does the pill show 'First connected on 30/04/2026' below the status? A: That's the historical first-connect date, kept as context. The live pill above it shows the row's CURRENT state (connected / linking / reconnect needed). We deliberately split these two so the pill never lies about current health while the historical date stays visible for users who want it.
Q: Will I lose my pending invites or data when I reconnect? A: No. Pending invites stay on LinkedIn — they're independent of WarmySender's connection state. Your prospects, audiences, conversations, sequences, sent metrics, and analytics are stored on our side and untouched by the reconnect. When campaigns resume, every prospect picks up at the exact step they were on.
Q: How long do I have to reconnect? A: Indefinitely. There's no hard deadline. But the longer you wait, the more pent-up backlog builds. After reconnecting, the platform respects per-account daily and weekly caps, so a long disconnect won't be 'caught up' in a burst — throughput rolls back to normal over the next 1-2 weeks.
Q: Is reconnecting safe? Will it trigger a flag on my LinkedIn account? A: Yes, it's safe. Reconnect uses LinkedIn's official authentication flow — the same secure handshake you use when you log in from a browser. No password is stored on our side, no 2FA is bypassed, no stale tokens are reused. LinkedIn treats it like any other normal login.
Q: Can I leave the account disconnected and reconnect later? A: Yes. Leaving an account disconnected is harmless — campaigns just stay paused at their current step. There's no penalty, no data loss, no LinkedIn-side flag for taking your time.
Q: I just reconnected but my campaigns are still paused. What now? A: The auto-resume sweeper runs every 5 minutes — give it one tick. If campaigns are still paused 10 minutes after reconnect, check that the LinkedIn account on LinkedIn → Accounts shows green 'Connected'. If green but campaigns still paused after 15 minutes, the campaigns may have an additional pause reason (manual pause, stuck-loop, subscription) — open the campaign and check the pause hint, then click Resume. If Resume immediately re-pauses, email support.
Q: I see two LinkedIn cards for the same person — why? A: This is a duplicate-OAuth pattern — almost always caused by clicking 'Reconnect' twice in quick succession before the first attempt finished its handshake. Each click previously issued a fresh OAuth session, so two live sessions ended up linked to the same LinkedIn identity (one with stale credentials, one with fresh). As of 2026-04-30 (Phase 5b follow-up F3), the Reconnect route caches the in-flight URL for 90 seconds so a second click within window returns the SAME reconnect URL — duplicates can no longer be created this way going forward. If you have an existing duplicate from before the fix, click the menu (⋮) on the older card and choose 'Disconnect'. Your campaigns are linked to the active card, so removing the older one is safe. If you're unsure which is which, email hello@warmysender.com with both account IDs and we'll confirm before you delete.
Q: Why does my account sometimes show 'Linking — finishing connection' for a long time? A: When you complete LinkedIn OAuth, the handshake has to land on three sides — LinkedIn → Unipile → WarmySender. In the rare case our final 'completeAccountConnection' callback throws or arrives out-of-order (a network race), Unipile holds the live session but our DB row stays at status='connecting' for longer than the typical sub-60-second window. The pill correctly shows 'Linking — finishing connection' (blue, spinner) for the first 5 minutes and 'Linking — taking longer than expected' (amber) after that. The hourly orphan watcher cron (introduced 2026-04-30) detects accounts where Unipile has the session but our row never linked, and self-heals by linking the row + flipping status='connected' + writing a paired audit row through the canonical state-flip helper. So even in the worst case, the pill clears within the hour without any action from you. If it persists past 60 minutes, click 'Reconnect' from the account menu — the F3 idempotency window (90s) ensures a single retry doesn't create a duplicate session.
Q: Why am I getting 'reconnect needed' emails when my dashboard already shows the account as connected? A: This is a stale internal health flag from a prior LinkedIn or Unipile-side outage. Your account is genuinely connected and our system is communicating with LinkedIn fine — but a derived 'health' marker on the row didn't reset when the reconnect succeeded, and our daily Health Alert email job kept firing on it. As of 2026-04-30 (LL#251), the reconnect path now resets that health marker alongside the other recovery markers, the alert email is gated to skip any account whose status is 'connected', and a 30-minute drift sentinel surfaces any future regression to admins before customers see it. Your campaigns, prospects, audiences, conversations, and pending invites are completely untouched by the fix — it's pure DB-state hygiene with zero LinkedIn or Unipile API calls. If you still see the email after the fix is deployed, click Reconnect once from LinkedIn → Accounts and the flag will reset cleanly on the next reconcile.
Q: Will the system ever delete my Unipile account without asking? A: No. Account safety always wins on the destructive direction. Every Unipile DELETE call site in the platform passes through a 6-layer defense: (1) env-var kill switch (default OFF for the reconciler — see LL#225), (2) sanity threshold abort (>5 absolute or >25% of fleet flips → abort + admin alert — LL#225), (3) per-account 3-poll 404 confirmation with 60s spacing — all three GET calls must return 404 before this delete fires (LL#239 Gate 5), (4) hard cap of 3 deletes per 24h measured against `linkedin_account_audit_log` (LL#239 Gate 6), (5) DB feature flag with 4h TTL on top of the env switch (LL#239 Gate 4), (6) audit-pairing trigger that rejects any status flip without a same-transaction audit row (LL#246). On top of all that, subscription-end cleanup is now non-destructive-by-default with a 7-day grace period (LL#230) and the only DELETEs that have actually fired in 2026 were operator-triggered, hardcoded, single-shot scripts (today: 2 inert duplicate sessions for Talha-old + Hafiz-old, after Phase 1 manual relinks were already complete — see PRD-2026-04-30). You will never see a silent fleet-wide cleanup. If a delete ever runs, it's logged with `[SENSITIVE-OP]` prefix and an `linkedin_admin_alerts` row.
Related guides: 'Why did my LinkedIn account disconnect — and how to reconnect' (longer deep-dive on the routine 30-day rotation, with auto-resume detail) at /documentation/linkedin-disconnect-and-reconnect; 'LinkedIn Campaign Documentation' (how schedule_days + sending windows + ramp interact, why acceptance can lag 1-3 days) at /documentation/linkedin; 'Why does my LinkedIn account show as disconnected?' (full Unipile state lifecycle: OK / CREDENTIALS / IN_APP_VALIDATION) at /documentation/linkedin-account-disconnected.
If your LinkedIn account suddenly shows a 'Reconnect' badge in WarmySender — and your campaigns paused on their own — this is almost always a routine LinkedIn session refresh, not a bug. This guide explains the cause in plain language, exactly what you'll see, how to fix it in under a minute, and what happens to your data.
The short version
LinkedIn rotates the session tokens that authenticate your account every ~30 days, and immediately on suspicious-login signals (new device or IP, password change, 2FA reset, security challenge). Our integration partner Unipile cannot silently refresh those tokens for security reasons — LinkedIn would flag a silent rebind as automation. The safest fix is for you to re-trigger the login flow once. Click the Reconnect button on the account, sign into LinkedIn, and you're done. Campaigns auto-resume within 5 minutes.
Why LinkedIn forces a re-login (the real reason)
LinkedIn issues every authenticated session a short-lived token. That token is what proves to LinkedIn that an action (sending an invite, fetching a profile, posting a comment) is coming from you, not a bot. LinkedIn rotates these tokens for security — exactly the same way your bank logs you out periodically. When the token expires or is invalidated, our integration partner Unipile reports the account's source status as 'CREDENTIALS', meaning the LinkedIn-side credential check failed and a fresh login is required. (See https://developer.unipile.com/docs/getting-started for technical detail.) Common triggers for this status:
Routine ~30-day rotation (most common; happens to every account, even healthy ones)
Password change on LinkedIn
2FA reset or new device verification
IP region change (you logged in from a different country, or your VPN/proxy IP rotated)
LinkedIn security challenge or CAPTCHA in the meantime
Idle session — the account was not actively used for a while
None of these are caused by WarmySender. Premium and Sales Navigator accounts get longer windows than free LinkedIn accounts, but every account eventually rotates.
What you'll see in WarmySender
When we detect the disconnect (within ~5 minutes via Unipile webhook + periodic health check), the platform takes three actions immediately:
1. The LinkedIn account row on LinkedIn → Accounts shows an amber or red 'Reconnect' badge next to the account name. The status pill switches from green 'Connected' to 'Reconnect needed'. 2. Every campaign attached to that account is auto-paused with paused_reason='linkedin_account_disconnected'. The campaign card shows a small hint: 'Will auto-resume after LinkedIn account reconnection.' 3. If the disconnect persists for more than 24 hours, we email you a one-click reconnect link from hello@warmysender.com with the subject 'Your LinkedIn account [Name] needs to be reconnected'. Clicking that email link drops you directly on the reconnect screen — no login to WarmySender required first.
How to reconnect (4 steps, ~30 seconds)
1. Open WarmySender and click LinkedIn → Accounts in the sidebar (or click the link in the reconnect email). 2. Find the affected account — it shows the amber 'Reconnect' badge. Click the 'Reconnect Account' button on that row. 3. You'll be routed to a hosted re-authentication page. Enter your LinkedIn email and password. If 2FA is enabled, enter the code. If LinkedIn shows a security challenge or CAPTCHA, complete it as you would any normal LinkedIn login. WarmySender never sees your password — Unipile handles the secure handshake with LinkedIn directly. 4. Return to WarmySender. The status pill flips back to green 'Connected' within seconds.
What happens after you reconnect
The self-heal sweeper (LL#206 + LL#231) runs every 5 minutes and automatically resumes any campaign paused with reason linkedin_account_disconnected once the underlying account is back to connected. You do not need to manually click Resume on each campaign. The platform also clears the failure-rate window so dead-account-era errors don't immediately re-pause anything. Account safety still wins on resume — sends respect your daily and weekly LinkedIn caps, sending window, ramp schedule, and active days. There is no burst catch-up of held-back invites, ever.
A campaign paused for any OTHER reason at the same time (manual pause, stuck-loop pause, subscription issue) may still need a manual Resume from its settings page. If you click Resume and it immediately re-pauses, contact support — that signals a stale failure window or a separate issue.
When to ask support
If reconnect fails twice in a row.
If the account stays stuck in 'Connecting…' status for more than 30 minutes.
If the account flips back to 'Reconnect needed' within an hour of a successful reconnect (this can mean a stale CHECK constraint on our side — a known edge case being actively patched in LL#236).
If you see frequent (more than once-a-week) disconnects on a Premium / Sales Navigator account.
Email hello@warmysender.com with the LinkedIn account email and approximate reconnect time. We'll dig into the specific row.
FAQ
Q: Will I lose my pending invites? A: No. Pending invites stay on LinkedIn — they are independent of WarmySender's connection state. Any invite already delivered to a prospect will still appear in their LinkedIn invitation queue, and any acceptance will still flow back to your dashboard via the 6h polling fallback even if the webhook missed it during the disconnect.
Q: Will recipients see I went offline, or that something changed? A: No. The disconnect is purely between WarmySender's integration layer and LinkedIn's auth system. From the recipient's point of view, nothing changed — you appear online or offline on LinkedIn exactly as you would normally. They never see a 'this user disconnected from a tool' signal because no such signal exists.
Q: Will I lose my campaign data, prospects, or audiences? A: No. Reconnecting only refreshes the auth token between WarmySender and LinkedIn. Your prospects, audiences, conversations, campaign sequences, sent metrics, and historical analytics are stored on our side and are completely untouched by the reconnect. When campaigns resume, every prospect picks up at the exact step they were on, including any 'wait for acceptance' or 'wait N days' delays in flight.
Q: How long do I have to reconnect? A: Indefinitely — there's no hard deadline. But the longer you wait, the more pent-up backlog builds in your campaigns. After reconnecting, the platform respects per-account daily and weekly caps, so a long disconnect won't be 'caught up' in a burst — throughput rolls back to normal over the next 1-2 weeks.
Q: Why does this happen even though my account is in good standing? A: LinkedIn's session rotation is unrelated to account standing. Even healthy, paid Sales Navigator accounts that have never been restricted hit the ~30-day rotation. Premium and Sales Navigator typically rotate less frequently than free accounts, but no account is exempt.
Q: Is reconnecting safe? Will it trigger a flag on my LinkedIn account? A: Yes, it's safe. Reconnect uses LinkedIn's official authentication flow — the same secure handshake you use when you log into LinkedIn from a browser. No password is stored on our side, no 2FA is bypassed, and no stale tokens are reused. LinkedIn treats reconnect exactly like any other login from your normal IP and device.
Q: Can I just leave the account disconnected and reconnect later when I have time? A: Yes. Leaving an account disconnected is harmless — campaigns just stay paused at their current step. There's no penalty, no data loss, and no LinkedIn-side flag for taking your time. Reconnect when you're ready and everything resumes.
Q: I just reconnected but my campaigns are still paused. What now? A: The auto-resume sweeper runs every 5 minutes — give it one tick. If campaigns are still paused 10 minutes after reconnect, check that the LinkedIn account on LinkedIn → Accounts shows green 'Connected' (sometimes the LinkedIn-side handshake takes a few extra seconds to complete). If the account is green but campaigns are still paused after 15 minutes, the campaigns may have an additional pause reason (manual, stuck-loop, etc.) — open the campaign and check the pause hint, then click Resume manually. If Resume immediately re-pauses, email support.
Reference: LL#206 (reconnect-clears-auto-pause + auto-resume sweeper, Apr 27, 2026), LL#231 (high-failure-rate self-heal companion sweeper, Apr 29, 2026), and LL#236 (Apr 29, 2026 reconnect CHECK-constraint edge case, fix in flight). For platform-wide reconnects after a major infrastructure rollout, see the separate 'Reconnecting your LinkedIn account after a platform update' guide.
Related guides: 'Why does my LinkedIn account show as disconnected?' (full Unipile state lifecycle), 'LinkedIn campaign auto-pause and resume' (campaign-side behavior), 'LinkedIn account safety and ramp' (why we never burst after a gap).
The 'acceptance rate' on your LinkedIn campaign dashboard is the percentage of sent invites that have been accepted by the prospect on LinkedIn. It is a real-time number, but it can lag the actual acceptance event by minutes (typically), hours (occasionally), or up to a day in rare cases — because of how LinkedIn delivers acceptance signals to us.
How we detect acceptances
There are two paths an acceptance signal can travel from LinkedIn into your dashboard:
Path A: Webhook (the fast path, usually seconds) When someone accepts your LinkedIn invite, LinkedIn fires an internal event. Our LinkedIn integration partner Unipile catches that event and posts it to a webhook on our side ('invite_accepted'). Our worker then stamps the prospect's record with the acceptance timestamp, advances them to the next step in your campaign sequence (e.g. 'send first message' after a 1-hour delay), and updates the acceptance count on your dashboard. End-to-end this is usually 5-30 seconds.
Path B: Polling fallback (catches anything the webhook missed, every 6 hours) LinkedIn's webhook delivery is not 100% reliable — it's network-based, and small fractions get dropped, delayed, or held in queues during incidents. To make sure no acceptance is ever silently missed, every 6 hours we poll each connected LinkedIn account's relations list (i.e. who is now your 1st-degree connection that wasn't yesterday) and reconcile any acceptance the webhook missed. The acceptance gets stamped with the actual time it happened, and your dashboard updates.
What 'pending' vs 'accepted' means
Pending — Your invite was sent and delivered to the prospect's invitation queue, but they have not accepted yet. They may accept later, ignore it, or decline.
Accepted — The prospect clicked Accept on LinkedIn. They are now your 1st-degree connection. We've received either the webhook or the 6h poll signal confirming this. Your campaign now routes them to the next step (typically the first follow-up message).
Withdrawn — You manually withdrew the invite, or it expired (LinkedIn auto-expires invitations after 6 months).
Why your acceptance rate may temporarily look low
Day 0 (campaign launch): 0% accepted is normal. People rarely accept invites within hours of receiving them. Most acceptances happen 1-3 days later.
Day 1-2: Real-world acceptance rate for cold LinkedIn invites is typically 20-40% (well-targeted), 40-60% (highly targeted with personalized notes), or 5-15% (untargeted). At Day 1, you should expect around 5-10% accepted because not everyone has logged into LinkedIn yet.
Day 3-7: Acceptance rate stabilizes near its true value. By Day 7 you have a meaningful number to evaluate.
If you sent invites yesterday and see '0% accepted' today, that is most likely correct — not a bug. Wait 48-72 hours before judging.
When the dashboard might mislead you
There is one known display issue we are fixing: in some cases the campaign overview page (the campaign list, not the per-campaign analytics page) reads acceptance rate from the wrong field and shows 0% even when the underlying data is correct. If you see 0% on the campaign list but the per-campaign analytics page shows real numbers, the data is correct — the list is wrong. The fix is shipping shortly. If you want the most accurate number, click into the campaign and view its analytics page.
If you suspect detection is broken
Detection is the system that records acceptances, not just the display. Detection is broken if you can confirm (via LinkedIn directly) that a specific person accepted your invite more than 24 hours ago AND your dashboard shows them as still 'pending'. To check:
1. Open LinkedIn in a browser, find the prospect's profile, and confirm you are 1st-degree connected. 2. Go to the prospect in WarmySender (LinkedIn → Audiences or via the campaign's prospect list). 3. Check the prospect's status. If LinkedIn shows you connected for >24h but WarmySender still shows 'pending', email hello@warmysender.com with the prospect's LinkedIn URL and the campaign name.
We page on-call automatically if no acceptance webhooks have been received platform-wide for >12 hours, so we usually catch broad outages before customers notice. But individual edge cases can still slip through.
Reading the dashboard correctly
Invited — count of unique prospects we sent an invite to.
Accepted (and acceptance rate) — count and percentage of those invites accepted so far.
Replied — count of prospects who replied to your follow-up message after accepting.
A healthy connection-then-message campaign typically shows: 30-50% acceptance rate, then 10-25% reply rate among accepted prospects. If acceptance is healthy but reply rate is very low, the issue is your message template, not the platform.
Audiences are collections of LinkedIn profiles used as targets for LinkedIn campaigns:
Creating Audiences:
From Find Prospects — Run a LinkedIn search, select profiles, and save them to a new or existing audience
Manual — Create an empty audience and add profiles individually
Import — Upload a CSV with LinkedIn profile URLs
Profile Enrichment: Enrichment fetches full profile data for each prospect in an audience — name, headline, company, location, job title, connection degree, and profile picture. This data enables personalization in your campaign messages using merge tags like {{firstName}}, {{company}}, and {{headline}}.
How Enrichment Works:
The system processes profiles in small batches (up to 15 per tick, every 3 minutes) to mimic natural LinkedIn browsing.
Each profile is fetched individually through your connected LinkedIn account — the same way you would view a profile manually on LinkedIn.
A daily cap limits how many profiles can be enriched per day based on your account strategy (see below).
When the daily cap is reached, enrichment pauses automatically and resumes at midnight UTC.
Enrichment results are cached for 30 days — if the same profile appears in another audience, cached data is reused instantly (no API call needed).
Enrichment Daily Caps (per account strategy): • New Account (week 1): ~10 profiles/day, increasing to 60/day by week 6 • Established (week 1): ~30 profiles/day, increasing to 80/day by week 4 • Veteran (week 1): ~50 profiles/day, increasing to 100/day by week 2 • Recovery: ~5 profiles/day, increasing to 30/day by week 8 These caps protect your LinkedIn account from being flagged for excessive profile viewing.
Estimated Enrichment Times: The Audiences page shows an estimated time remaining based on your daily cap. For large audiences on new accounts, enrichment can take multiple days. Examples: • 100 profiles on a veteran account: ~1-2 days • 500 profiles on a new account (week 1): ~50 days at 10/day cap • 1,000 profiles on an established account: ~13-33 days depending on ramp week As your account ages and advances through ramp weeks, the daily cap increases and enrichment speeds up.
Why Enrichment Uses Your LinkedIn Account: LinkedIn requires an authenticated session to view profile data — there is no public API or way to access profiles without a logged-in account. Using a shared 'system' account is not possible because: • LinkedIn actively detects and bans accounts that view profiles at scale from a single source • A shared account would be banned within hours, affecting all users • Your own account sees network-specific data (connection degree, mutual connections) that a third-party account cannot access • This is how all LinkedIn automation tools work — each user must use their own authenticated account
Is Enrichment Required to Start a Campaign? No — enrichment is completely optional. You can create and launch a LinkedIn campaign immediately without waiting for enrichment to complete. Campaigns use LinkedIn profile URLs to send connection requests and messages. Enrichment simply adds extra profile details (name, company, headline) that enable richer personalization with merge tags. If enrichment is incomplete, campaigns still work — you just may have fewer personalization fields available for unenriched profiles.
Audience-to-Prospect Linking: Enriched profiles are automatically linked to your Prospects table. LinkedIn-specific fields are populated: member ID, profile URL, headline, company, and location.
Using Audiences in Campaigns: When creating a LinkedIn campaign, select one or more audiences as the target. Prospects from the audience are enrolled into the campaign steps. You can start the campaign immediately — enrichment continues in the background and data becomes available as profiles are enriched.
FAQ:
Q: Why is my enrichment showing 16 days remaining? A: The daily cap depends on your account strategy and ramp week. New accounts start with a low cap (~10 profiles/day) to protect your LinkedIn account. As your account ages and progresses through ramp weeks, the cap increases. For large audiences (500+ profiles), initial enrichment can take multiple days. You do not need to wait — start your campaign now and enrichment will continue in the background.
Q: My enrichment stopped or failed — what happened? A: Common causes: 1) Your LinkedIn account disconnected during enrichment — reconnect from LinkedIn > Accounts and restart enrichment. 2) Daily cap reached — enrichment pauses until midnight UTC and resumes automatically. 3) Circuit breaker triggered — if too many errors occur (10+ in a day), enrichment stops to protect your account. Reconnect your account and retry.
Q: Can I speed up enrichment? A: The enrichment rate is intentionally conservative to protect your LinkedIn account. Faster enrichment would risk LinkedIn restrictions or bans. As your account moves to higher ramp weeks (2-6 weeks after connection), the daily cap automatically increases. Veteran accounts (1+ year old) have the highest caps.
Q: Does enrichment count toward my LinkedIn daily limits? A: Yes, enrichment uses profile view API calls that share the daily limit with campaign 'View Profile' steps. If you have active campaigns with profile view steps, they share the same daily cap.
Tip: Build targeted audiences using Sales Navigator filters for best results. Quality over quantity — a smaller, well-targeted audience will outperform a large, generic one.
Create and manage LinkedIn-only outreach campaigns from the LinkedIn section.
Creating a LinkedIn Campaign:
Go to LinkedIn > Campaigns from the sidebar.
Click 'Create Campaign' and give your campaign a name.
Select the LinkedIn account to use for sending.
Select an audience — choose one or more audiences as campaign targets.
Define your campaign steps — build a sequence using LinkedIn action types.
Do I Need to Wait for Enrichment? No. You can create and start a LinkedIn campaign immediately, even if your audience is still being enriched or has not been enriched at all. Campaigns only need LinkedIn profile URLs to function — they can send connection requests, messages, and InMails using the profile URL alone. Enrichment adds extra data (name, company, headline) for personalization, but it is not a prerequisite. Start your campaign now and enrichment will continue running in the background. As profiles are enriched, personalization data becomes available for subsequent campaign steps.
Campaign Types:
Connection Request then Message — Send an invite, wait for acceptance, then follow up with a direct message. Most common approach for warm outreach.
InMail Sequences — For reaching non-connections using LinkedIn Premium or Sales Navigator InMail credits. No connection request needed.
Mixed sequences — Combine profile views, connection requests, messages, and InMails with conditional branches based on whether the prospect accepted or replied.
Daily Limits & Sending Windows: Set daily action limits per campaign to stay within safe thresholds. Configure sending windows (start/end hours and timezone) and active days to control when LinkedIn actions are executed. The system enforces account-level safety limits on top of your campaign settings.
Monitoring Active Campaigns: Track key metrics from the campaign dashboard: • Invites Sent — Total connection requests dispatched • Accepted — How many prospects accepted your invite • Messages Delivered — Direct messages and InMails sent • Replies — Number of prospect responses
Managing Campaigns:
Pause — Temporarily stop all actions while preserving progress. Prospects stay at their current step.
Resume — Continue a paused campaign from where it left off.
Complete — Mark a campaign as finished. No further actions will be sent.
Campaigns are automatically paused if your LinkedIn account is disconnected or restricted.
FAQ:
Q: My audience says enrichment is in progress — can I still start my campaign? A: Yes. Enrichment is a background process that adds profile details for personalization. Your campaign will start immediately using the LinkedIn URLs in your audience. You do not need to wait for enrichment to complete.
Q: Will my campaign messages be less effective without enrichment? A: If you use merge tags like {{firstName}} or {{company}} in your message templates, those fields will only be populated for enriched profiles. For unenriched profiles, you can set Liquid syntax fallbacks (e.g., {{firstName | default: 'there'}}) to handle missing data gracefully. Connection requests without personalization still work — you can always send blank invites.
Q: My campaign shows 0 prospects enrolled — what went wrong? A: This usually means your audience has no profiles with LinkedIn URLs, or the profiles could not be matched. Check your audience on the Audiences page to verify it has profiles. If you imported via CSV, make sure the linkedinUrl column was mapped correctly.
View and manage LinkedIn post engagement from the LinkedIn section.
Accessing Posts: Go to LinkedIn > Posts from the sidebar to see post activity across your connected LinkedIn accounts.
Post Engagement: Track how your LinkedIn posts are performing and manage engagement. Use post activity as a touchpoint in your outreach strategy — engaging with a prospect's posts before reaching out can significantly increase connection acceptance and reply rates.
Tracking Performance: Monitor key post metrics to understand what content resonates with your audience. Use these insights to refine your LinkedIn content strategy and support your outreach efforts.
Automate LinkedIn post engagement through the WarmySender REST API. The LinkedIn Likes API lets you programmatically add reactions to posts using API key authentication — perfect for AI agents, CRM integrations, and automated outreach workflows.
Getting Started:
Go to Settings > API Keys and create a new API key.
Select the 'linkedin:read' and 'linkedin:write' scopes.
Copy your API key (shown once — save it securely).
Use the key in the Authorization header: Authorization: Bearer YOUR_API_KEY
Available Endpoints:
GET /api/v1/linkedin/accounts — List your connected LinkedIn accounts with daily engagement limits and remaining quota.
POST /api/v1/linkedin/posts/{postId}/reactions — Add a reaction to a LinkedIn post. Requires linkedin_account_id and optional reaction_type (LIKE, CELEBRATE, SUPPORT, LOVE, INSIGHTFUL, FUNNY) in the request body.
GET /api/v1/linkedin/posts/{postId}/reactions — List all reactions on a post. Requires linkedin_account_id as a query parameter.
Post ID Format: The postId is the LinkedIn post URN in the format 'urn:li:activity:1234567890'. When placing it in the URL path, URL-encode the colons: urn%3Ali%3Aactivity%3A1234567890
Account Safety & Rate Limits: Daily engagement limits are enforced per LinkedIn account based on account age and strategy. This protects your LinkedIn account from being flagged: • New accounts (< 6 months): Start at 5 engagements/day, ramp to 30 over 6 weeks • Established accounts (6-12 months): Start at 15/day, ramp to 40 over 4 weeks • Veteran accounts (1+ year): Start at 25/day, ramp to 50 over 2 weeks • Recovery (after restriction): Start at 2/day, very slow 8-week ramp to 15/day The API returns 429 with details when the daily limit is reached.
Use Cases:
1. AI Sales Agents — Build AI agents that engage with prospects' posts before sending connection requests. Liking a post signals interest and increases acceptance rates.
2. Pre-Outreach Warming — Like a prospect's recent post on Day 1, then send a cold email or connection request on Day 3. This multichannel touch builds familiarity.
3. CRM-Triggered Engagement — Connect your CRM to automatically like posts from high-value leads when they publish new content.
4. Content Monitoring — Use the GET reactions endpoint to monitor engagement on target posts and identify trending content for outreach timing.
5. Multi-Account Rotation — If you have multiple LinkedIn seats, distribute likes across accounts to maximize daily engagement capacity.
For full API documentation with code examples, visit the API Reference page at /docs/integrations.
LinkedIn templates serve as reusable building blocks for your outreach campaigns. Here is how they work and why they matter:
What Templates Do:
Templates are pre-written messages stored in your template library (LinkedIn > Templates).
They save time when creating multiple campaigns — instead of writing from scratch every time, select a proven template as your starting point.
Templates support merge tags ({{firstName}}, {{company}}, {{headline}}) so they auto-personalize for each prospect.
Why You Edit Messages in Campaigns:
When you create a campaign step and select a template, the template content is copied into the step as a starting point.
You can then customize the message for that specific campaign's audience without changing the original template.
This is by design — your template library contains your general frameworks, while each campaign step can be tailored to the specific audience.
Think of it like a document template in Word: you start from a template but customize each document.
Template Types:
Invite Note (300 character limit) — For connection request personalization.
Message (8,000 character limit) — For direct messages to connections.
InMail (8,000 character limit) — For InMail messages to non-connections.
Workflow:
Create templates in LinkedIn > Templates for your best-performing messages.
When building a campaign step, click the template picker to select one.
The template content fills the step editor — customize it for this specific campaign.
Changes to the step do NOT modify the original template (they are independent after selection).
For frequently used messages, save them as templates so you can reuse them across campaigns.
Auto-Created Templates: When you write a message directly in a campaign step without selecting from the library, the system may auto-create a template (marked with '(Auto)' suffix) for that step. These auto-templates are campaign-specific and update in-place, unlike library templates which are copy-on-write protected.
WarmySender automatically protects each connected LinkedIn account with a dedicated proxy — ensuring your activity appears to originate from a consistent, geographically plausible IP address rather than a shared server.
Why Proxies Matter: LinkedIn monitors the IP addresses used to access accounts. If your account is accessed from a data center IP, or if multiple accounts share the same IP, LinkedIn may flag or restrict your account. WarmySender solves this by routing all LinkedIn activity through a fixed, dedicated proxy assigned to your account — so your traffic always appears consistent and natural.
Key Principles for Account Safety:
Consistency — The same IP is used every time (no rotation)
Geographic plausibility — Proxy is near your real location
Exclusivity — Your proxy is not shared with other accounts
How It Works:
When you connect a LinkedIn account, WarmySender assigns a dedicated fixed IP address to that account
All LinkedIn requests for that account are routed through the assigned proxy — never directly from WarmySender servers
The proxy IP is fixed (no rotation) and not shared with any other LinkedIn account
The proxy remains assigned for the lifetime of the connection, ensuring a consistent IP footprint
Proxy Modes: You configure your proxy during Step 2 of the LinkedIn account connection wizard. Three modes are available:
Auto (default) — WarmySender assigns a proxy automatically, geo-located near your detected IP. Best choice for most users — requires no configuration.
Country — You select a specific country for your proxy location. Useful if your LinkedIn account was originally registered from a different country, or if you operate across regions.
Custom — You provide your own proxy URL. Full control over your IP. Supports HTTP, HTTPS, and SOCKS5 protocols with optional username/password authentication.
Types of Proxies: Depending on the selected country and availability, WarmySender uses either ISP-grade (residential-quality) or datacenter proxies. The most important factors for account safety are consistency and geographic plausibility — not the specific proxy type. LinkedIn does not distinguish between ISP and datacenter proxies. Each account always gets a single dedicated IP regardless of type.
Supported Countries (Country Mode): 40+ countries are available. Countries with guaranteed availability include: • Americas: United States, Canada, Brazil • Europe: United Kingdom, Germany, France, Switzerland, Austria, Netherlands, Belgium, Italy, Spain, Portugal, Sweden, Norway, Denmark, Ireland • Asia-Pacific: Singapore, Japan, India, Australia • Middle East: United Arab Emirates
Additional countries may be available depending on current inventory. The full list is shown during account setup.
Custom Proxy Setup: If you select Custom mode, enter your proxy URL in this format: protocol://username:password@host:port
Examples:
http://myuser:mypass@proxy.example.com:8080
socks5://myuser:mypass@proxy.example.com:1080
https://proxy.example.com:443 (no authentication)
Supported protocols: http, https, socks5. If your proxy uses IP allowlisting instead of credentials, omit the username:password@ portion.
Frequently Asked Questions:
Q: Can I change my proxy after connecting an account? A: Proxy settings are configured during account connection. To change your proxy, disconnect and reconnect the account with new proxy settings. During reconnection, you can select a different proxy mode.
Q: Do all accounts share the same proxy? A: No. Every connected LinkedIn account gets its own dedicated IP address. Accounts are never co-mingled on the same proxy.
Q: Does proxy type (ISP vs datacenter) affect my account safety? A: Consistency and geo-plausibility matter far more than proxy type. A consistent datacenter IP near your real location is safer than a rotating residential IP from a different country.
Q: What if I don't choose a proxy mode? A: Auto mode is applied by default. WarmySender assigns the closest available proxy to your real IP location.
Q: Can I use a free public proxy? A: This is not recommended. Free proxies are often shared, unreliable, or already flagged by LinkedIn. Use a reputable paid proxy provider if choosing Custom mode.
Q: Does WarmySender rotate my IP? A: No. Each account gets a single fixed IP. IP rotation can look suspicious to LinkedIn — consistency is safer.
InMail lets you message LinkedIn members you are not connected with. Here is how to use it effectively.
What Is InMail? • InMail is a LinkedIn Premium/Sales Navigator feature that lets you message people outside your network. • You get a limited number of InMail credits per month (varies by subscription). • Credits are refunded if the recipient responds within 90 days.
When to Use InMail vs. Connection Request:
Use InMail for: Senior executives who rarely accept connection requests, time-sensitive outreach, when you have a highly relevant message.
Use Connection Requests for: Peers in your industry, people you share mutual connections with, building long-term relationships.
InMail response rates average 10-25% (vs. 20-40% for connection requests from well-optimized profiles).
Writing Effective InMails:
Subject Line (Critical):
Keep under 40 characters.
Personalize: '{{firstName}}, quick thought about {{company}}'
Edit your LinkedIn profile directly from WarmySender without leaving the platform.
Editable Fields: - Headline — Your professional title shown below your name (max 220 characters) - Summary/About — The About section on your profile (max 2,600 characters) - Open to Work — Toggle whether your profile shows the 'Open to Work' badge
How to Edit:
Go to LinkedIn > Accounts
Click on an account to open details
Click 'Edit Profile' at the bottom of the dialog
Update your headline, summary, or Open to Work status
Click 'Save'
Changes are applied directly to your LinkedIn profile via the API. They may take a few minutes to appear on LinkedIn.
Tip: A compelling headline increases connection acceptance rates. Consider updating it before launching outreach campaigns.
Manage your LinkedIn messages with delete, edit, and reaction capabilities.
Deleting Messages: You can delete messages you sent within the last 60 minutes. This is a LinkedIn platform limitation — after 60 minutes, deletion is no longer possible. 1) Open a conversation in LinkedIn > Conversations 2) Hover over a message you sent within the last hour 3) A trash icon appears — click it 4) Confirm the deletion in the dialog 5) The message is removed from both WarmySender and LinkedIn
Deleting Conversations: Entire conversations can be deleted from the conversation list. 1) Hover over a conversation in the list 2) Click the trash icon 3) Confirm deletion 4) The conversation is removed from both platforms
Message Reactions: Add emoji reactions to any message in a conversation. 1) Hover over a message 2) Click the smiley face icon 3) Choose from 6 emoji options 4) The reaction is sent to LinkedIn
Note: Message deletion is permanent and cannot be undone. The 60-minute window is enforced on both the client and server side for security.
The LinkedIn Analytics page now includes additional insights about your network and engagement activity.
Followers Section: View a list of your LinkedIn followers with their profile pictures, names, and headlines. Select an account to see its followers. Use 'Load More' for pagination.
Engagement History: Two side-by-side panels show your recent activity: - Recent Comments — Comments you've made on LinkedIn posts - Recent Reactions — Reactions (likes, celebrates, etc.) you've given
Account Health Actions: Two new maintenance actions are available for each LinkedIn account:
Resync Messages — Refreshes your messaging data from LinkedIn. Use this if messages appear out of sync or are missing. This is a lightweight operation.
Restart Connection — Reinitializes your LinkedIn connection. Use this as a last resort if your account is behaving unexpectedly. This is a heavier operation and requires confirmation.
These features appear at the bottom of the existing Analytics page — scroll down past the campaign performance and account health sections.
Recruiter Search Filters are an advanced set of search parameters available exclusively to users who have connected a LinkedIn Recruiter account to WarmySender. These filters go beyond the standard search options (keywords, location, industry, skills, schools) and let you pinpoint prospects based on tenure, employment type, education level, and result ordering. If your connected account is a Free, Premium, or Sales Navigator account, these filters will not appear — you will see an informational message explaining why.
Available Filters Explained
1) Tenure at Current Position (Min / Max Months) Specify the minimum and maximum number of months a prospect has held their current role. This is one of the most powerful filters for outreach because tenure correlates strongly with buying intent and openness to change. - Min Months: Only include prospects who have been in their current position for at least this many months. - Max Months: Only include prospects who have been in their current position for no more than this many months. - Example: Setting min=0 and max=6 finds people who recently started a new role — they are often evaluating new tools and vendors. - Example: Setting min=24 and max=120 finds people who have been in their role for 2-10 years — they likely have budget authority and established decision-making power.
2) Employment Type Filter prospects by their current employment arrangement. You can select one or more of the following: - Full-time — Target traditional full-time employees, ideal for enterprise sales. - Part-time — Reach part-time workers, useful for flexible staffing solutions. - Contract — Find contractors and consultants who may need tools or services for their engagements. - Internship — Target interns, useful for entry-level recruiting or educational products. Note: Some employment type options may require a Recruiter PRO subscription on LinkedIn's side.
3) Degree Include / Exclude Filter results based on the education level listed on prospects' LinkedIn profiles. - Include: Only show prospects who have one of the specified degree types (e.g., Bachelor's, Master's, MBA, PhD). - Exclude: Remove prospects who have a specific degree type from your results. - Important: Many LinkedIn profiles do not list education details. Using degree filters aggressively may exclude a large portion of otherwise qualified prospects. Use this filter as a refinement tool, not as your primary filter.
4) Sort By Control how your search results are ordered: - Relevance (default) — LinkedIn ranks results by how well they match your overall search criteria. - Alphabetical — Results sorted by prospect name, useful when scanning a large result set systematically. - Newest First — Surfaces profiles that were most recently updated or created, helping you find active LinkedIn users.
Use Cases
Scenario 1: Find Decision-Makers New in Their Role Set tenure min=0, max=6 months, combined with a senior job title keyword like 'VP' or 'Director' and your target industry. People who recently started a senior role are actively evaluating tools, renegotiating vendor contracts, and open to introductions. This is one of the highest-converting outreach segments.
Scenario 2: Target Contractors and Freelancers Select Employment Type = Contract. Combine with industry and skills filters to find independent consultants who may need your product or service for their client engagements. Contractors often have faster purchasing cycles since they make their own tool decisions.
Scenario 3: Exclude Entry-Level Prospects by Education If your product targets experienced professionals, use Degree Exclude to remove 'Internship' employment types and optionally exclude certain degree levels. This narrows your list to more experienced prospects without manually reviewing each profile.
Scenario 4: Find People with Budget Authority (2+ Years in Role) Set tenure min=24 months. Prospects who have been in their role for two or more years typically have established budgets, authority to approve purchases, and a clear understanding of their team's pain points. Combine with title keywords like 'Manager', 'Head of', or 'Director' for best results.
Step-by-Step Guide
Step 1: Select a Recruiter Account Go to LinkedIn > Campaigns or LinkedIn > Search. In the account selector dropdown, choose a connected LinkedIn account that has Recruiter-tier access. If you are unsure of your account type, check the LinkedIn > Accounts page where each account shows its tier.
Step 2: Open Advanced Recruiter Filters Below the standard search filters (keywords, location, industry, etc.), look for the 'Advanced Recruiter Filters' section. This section only appears when a Recruiter-tier account is selected. Click to expand it.
Step 3: Configure Each Filter - Tenure: Enter min and/or max months in the input fields. Leave blank to skip this filter. - Employment Type: Check one or more checkboxes (Full-time, Part-time, Contract, Internship). - Degree Include: Type degree names to add them to the include list. - Degree Exclude: Type degree names to add them to the exclude list. - Sort By: Select from the dropdown (Relevance, Alphabetical, Newest First).
Step 4: Run Your Search Click 'Search' to execute. All filters combine with AND logic — a prospect must match every active filter to appear in results. For example, if you set tenure min=6 AND employment type=Full-time AND industry=Technology, only full-time technology professionals who have been in their role for at least 6 months will appear.
Non-Recruiter Users
If your connected LinkedIn account is Free, Premium, or Sales Navigator tier, the Advanced Recruiter Filters section will not appear. Instead, you will see an informational message: 'Recruiter filters require a LinkedIn Recruiter account.' You can still use all standard search filters (keywords, location, industry, company size, skills, schools, job title, seniority, and more). To access Recruiter filters, you need to connect a LinkedIn account that has an active Recruiter or Recruiter Lite subscription and reconnect it through the LinkedIn > Accounts page.
Best Practices
Combine Tenure with Industry for Precision — Tenure alone returns a broad set. Adding an industry filter (e.g., 'SaaS', 'Financial Services') dramatically narrows results to relevant prospects.
Use Degree Filters Sparingly — A significant percentage of LinkedIn profiles have incomplete education sections. Over-relying on degree filters can exclude qualified prospects who simply haven't filled out their education. Use degree as a secondary refinement, not a primary filter.
Start Broad, Then Narrow Down — Begin with just one or two filters and review the result count. If you get too many results, add more filters incrementally. Starting too narrow risks missing good prospects.
Use Sort By Newest First for Active Profiles — Sorting by newest first helps you reach people who are actively updating their LinkedIn presence. These prospects are more likely to see and respond to your outreach.
Save Your Search Criteria — Once you find a filter combination that produces good results, note the settings so you can replicate them across campaigns. LinkedIn Recruiter also supports saved searches with a 'New Results Only' toggle to see fresh matches.
Respect Account Safety — Even with precise filters, always stay within WarmySender's daily action limits. Better targeting means fewer wasted actions, but never exceed the recommended daily outreach volume.
Frequently Asked Questions
Q: Which LinkedIn account types support Recruiter filters? A: Only LinkedIn Recruiter and Recruiter Lite accounts. Free, Premium Career, Premium Business, and Sales Navigator accounts do not have access to these filters.
Q: Can I save my Recruiter search and reuse it later? A: Yes. LinkedIn Recruiter supports saved searches. In WarmySender, you can reference a saved search by its ID and toggle 'New Results Only' to see only prospects added since your last search.
Q: Do Recruiter filters work with campaign auto-search? A: Yes. When you create a LinkedIn campaign with auto-search enabled, any Recruiter filters you configure will be applied each time the campaign searches for new prospects.
Q: What happens if I disconnect my Recruiter account? A: The Recruiter filter section will disappear and your searches will fall back to standard filters only. Any campaigns using Recruiter-specific filters will continue to run but will skip the Recruiter-only parameters.
Q: Can I combine Recruiter filters with the standard filters? A: Absolutely. Recruiter filters are additive. You can use keywords, location, industry, skills, company size, schools, seniority, and all other standard filters alongside the Recruiter-specific ones. All filters combine with AND logic.
Skill endorsements let you endorse a prospect's LinkedIn skills as a lightweight engagement action that builds rapport, triggers a notification on their end, and warms up the relationship before you send a connection request or message. This feature is available both as a campaign step and as a standalone action from any prospect's profile.
—— OVERVIEW ——
When you endorse someone's skill on LinkedIn, they receive a notification with your name and photo. This puts you on their radar without requiring them to accept anything. Unlike connection requests or InMails, endorsements are non-intrusive — the prospect sees your name, may visit your profile out of curiosity, and is more likely to accept a follow-up connection request from someone who already engaged with them. Studies show that prospects who receive an endorsement before a connection request accept at 2-3x the rate of cold invites.
How It Works Under the Hood: When the endorsement step executes, WarmySender fetches the prospect's full LinkedIn profile via the Unipile API, extracts all skills that have endorsement IDs, matches your preferred skill name (if you specified one), and submits the endorsement. The entire process is automated and takes a few seconds per prospect.
—— USE CASES ——
1) Warm Up Cold Prospects Before Connection Requests The most common use case. Place an 'Endorse Skill' step before your 'Send Invite' step in a campaign sequence. The prospect receives the endorsement notification, sees your name and profile photo, and when your connection request arrives 1-2 days later, you are no longer a complete stranger. This dramatically improves acceptance rates, especially for senior decision-makers who ignore cold invites.
2) Re-engage Dormant Leads Who Did Not Accept Your Invite If a prospect has not accepted your connection request after 7-14 days, an endorsement serves as a gentle nudge. It reminds them you exist without being pushy. Place it after a 'Wait Accept' timeout step in your campaign. Many prospects will revisit your pending invite after receiving the endorsement notification.
3) Build Social Proof Through Reciprocity People naturally want to return favors. When you endorse a prospect's skill, many will visit your profile and endorse one of your skills in return. This creates a mutual engagement loop. Even if they do not endorse back, the profile visit alone increases your visibility and makes future outreach warmer.
4) SDR Teams Using Endorsements as a First Touchpoint For sales development teams running high-volume outreach, endorsements provide a low-risk first touchpoint that does not consume your daily connection request quota. An SDR can endorse 15-20 prospects per day, then follow up with connection requests the next day — effectively doubling the touchpoints without doubling the risk.
—— STEP-BY-STEP CAMPAIGN SETUP ——
Adding Endorse Skill to a Campaign: 1) Go to LinkedIn > Campaigns and create a new campaign or edit an existing one 2) In the campaign editor, click 'Add Step' 3) From the Actions menu, select 'Endorse Skill' 4) Configure the step: • Preferred Skill (optional) — Enter a specific skill name like 'Python', 'Sales Strategy', or 'Product Management'. The system will try to match this against the prospect's listed skills. • If left blank, the system automatically endorses the first available skill on the prospect's profile. 5) Set an appropriate delay before this step (recommended: 0-1 days if it is the first step, or 1-2 days between steps) 6) Save your campaign
Best Placement — Before Send Invite (Cold Outreach): This is the recommended sequence for cold outreach campaigns: Step 1: View Profile (day 0) — Triggers a 'someone viewed your profile' notification Step 2: Wait 1 day Step 3: Endorse Skill (day 1) — Triggers a second notification with your name Step 4: Wait 1 day Step 5: Send Invite with personalized note (day 2) — They already recognize your name This three-touch warm-up sequence (view, endorse, invite) consistently outperforms single-step cold invites.
Alternative Placement — After Wait Accept Timeout (Re-engagement): Use this sequence when a prospect has not accepted your connection request: Step 1: Send Invite (day 0) Step 2: Wait Accept — timeout after 7 days Step 3: Endorse Skill (day 7) — Gentle nudge if invite was not accepted Step 4: Wait 3 days Step 5: Follow Up (if connected) or end campaign The endorsement after a timeout acts as a reminder without being aggressive.
Advanced Placement — Combined with Like/Comment: For high-value prospects, combine endorsements with other engagement actions: Step 1: View Profile (day 0) Step 2: Endorse Skill (day 1) Step 3: Like Post (day 2) — Like one of their recent posts Step 4: Send Invite (day 3) — By now they have seen your name 3 times This multi-touch approach works best for C-level executives and hard-to-reach prospects.
—— STANDALONE ENDORSEMENT GUIDE ——
You can also endorse skills outside of campaigns, directly from a prospect's profile:
Go to LinkedIn > Conversations or search for a prospect
Click on the prospect's name to open their profile details
Scroll to the 'Skills' section — you will see their listed LinkedIn skills
Click the 'Endorse' button next to the skill you want to endorse
The endorsement is submitted immediately and logged in the prospect's activity timeline
When to Use Standalone Endorsements:
Before sending a manual connection request or message
After a conversation goes cold — a subtle way to re-appear in their notifications
When researching a prospect and you want to leave a positive impression
To thank someone who engaged with your content or accepted your invite
—— BEST PRACTICES & GUIDELINES ——
Always endorse relevant skills — Match the skill to their industry and role. A CTO should be endorsed for 'Cloud Architecture' or 'Technical Leadership', not 'Microsoft Word'. Relevant endorsements show you actually looked at their profile.
Avoid generic skills — Do not endorse skills like 'Microsoft Office', 'Communication', or 'Teamwork'. These feel impersonal and spam-like. Choose skills that reflect their professional expertise and seniority.
Limit to 1 endorsement per prospect — Endorsing multiple skills on the same person looks automated and suspicious. One well-chosen skill endorsement is far more effective than three generic ones.
Space endorsements throughout the day — Do not endorse 15 prospects in 5 minutes. WarmySender automatically spaces actions throughout your sending window, but if using standalone endorsements manually, wait at least 5-10 minutes between each.
Combine with profile view for better warm-up — A profile view followed by a skill endorsement (with a 1-day gap) creates a natural-looking engagement pattern. The prospect sees 'Someone viewed your profile' and then 'Someone endorsed your skill' — this feels organic, not automated.
Use the preferred skill field strategically — If you are targeting a specific industry (e.g., SaaS sales leaders), set the preferred skill to something common in that niche like 'SaaS Sales' or 'Sales Strategy'. This ensures every endorsement in the campaign feels relevant.
Review endorsement results — Check the campaign step analytics to see how many endorsements were successfully delivered vs. skipped. A high skip rate means your target audience does not list many skills, and you may want to adjust your approach.
—— RATE LIMITS & SAFETY ——
Endorsements share the daily engagement limit with post likes and comments. Here is the ramp-up schedule:
Days 1-3 (New Account): Max 5 endorsements per day
Days 4-7 (Warming Up): Max 10 endorsements per day
Days 8-14 (Established): Max 15 endorsements per day
Days 15+ (Fully Ramped): Max 20 endorsements per day
These conservative limits protect your LinkedIn account from being flagged for unusual activity. The system automatically tracks your daily usage and will defer remaining endorsements to the next day if you hit the limit.
What Happens at the Limit:
The endorsement step is paused and queued for the next available day
The enrollment is NOT failed — it simply waits
You receive a notification in the campaign dashboard showing 'Rate limited — will retry tomorrow'
Other step types (messages, invites) are not affected by the endorsement limit
Account Safety Notes:
Endorsements are one of the lowest-risk LinkedIn actions — they rarely trigger account restrictions
However, endorsing dozens of people you have no connection to in rapid succession can look suspicious
WarmySender adds randomized delays (30-120 seconds) between endorsement actions to mimic human behavior
If your LinkedIn account is in a restricted state, all actions including endorsements are automatically paused
—— TROUBLESHOOTING ——
• No Skills Found on Prospect's Profile Some LinkedIn users do not have any skills listed, or their skills section is hidden. When this happens, the endorsement step is automatically skipped and the enrollment advances to the next step. The campaign does not fail. You will see 'Skipped — no endorsable skills found' in the step log. This is normal and affects roughly 10-15% of prospects.
• Endorsement Failed with an Error If the endorsement API call fails (e.g., due to a temporary LinkedIn outage or API rate limit), the system retries up to 2 times with a 5-minute delay between attempts. If all retries fail, the step is marked as 'Failed' but the enrollment continues to the next step. Check the error message in the campaign logs for details.
• Preferred Skill Name Not Matching The skill matching is case-insensitive and uses partial matching. If you specify 'Python' as the preferred skill, it will match 'Python', 'Python Programming', or 'Python Development'. However, if the prospect does not have any skill containing your keyword, the system falls back to endorsing the first available skill. To avoid mismatches, use broad skill keywords rather than very specific ones.
• Endorsement Succeeded but Prospect Did Not Get Notified LinkedIn controls notification delivery. In rare cases, the prospect may have notifications turned off for endorsements, or LinkedIn may batch the notification into a digest email. The endorsement still appears on their profile and is visible to them when they view their skills section.
• Duplicate Endorsement Warning If you have already endorsed a prospect's skill (from a previous campaign or manual action), the system detects this and skips the step to avoid sending a duplicate. This is logged as 'Skipped — already endorsed' in the step log.
—— FREQUENTLY ASKED QUESTIONS ——
1) Can I endorse someone I am not connected with? Yes. LinkedIn allows you to endorse skills on anyone's public profile, even if you are not connected. This is what makes endorsements such an effective pre-connection warm-up action.
2) Will the prospect know I used an automation tool? No. The endorsement appears exactly the same as a manual endorsement. LinkedIn shows your name and profile photo in the notification. There is no indication that it was sent via an API or automation tool.
3) Can I undo an endorsement after it is sent? Endorsements can be manually removed from LinkedIn's web interface, but WarmySender does not provide an undo feature. This is why it is important to endorse relevant skills — you want the endorsement to reflect well on you if the prospect views it.
4) Should I endorse prospects who are already connected with me? Generally no, unless you are using it as a re-engagement tactic for dormant connections. For active connections, direct messaging is more effective. Endorsements are most powerful as a pre-connection or re-engagement tool.
5) How do endorsements interact with other campaign steps? Endorsements are independent of other step types. They do not consume your connection request or message quotas. They share the engagement limit with likes and comments only. You can safely combine endorsement steps with any other step type in the same campaign without worrying about quota conflicts.
The Publishing page lets you create LinkedIn posts, repost content, and track your engagement history — all from within WarmySender. Content publishing is a powerful complement to your outreach strategy: prospects who see your posts before receiving a connection request are significantly more likely to accept.
Why Content Publishing Matters for Outreach: LinkedIn is not just a messaging platform — it is a content platform. Prospects check your profile before accepting connection requests, and a profile with zero posts looks inactive or spammy. Publishing regular, valuable content establishes you as a real professional with genuine expertise, making your outreach feel less like cold selling and more like professional networking. SDR teams that combine content publishing with connection campaigns see 30-50% higher acceptance rates compared to outreach alone.
Use Cases:
Thought Leadership Before Cold Outreach — Publish 2-3 insightful posts about your industry before launching a connection campaign. When prospects see your invite and check your profile, they find valuable content instead of an empty feed. This dramatically improves acceptance rates.
Sharing Industry Insights to Attract Inbound Leads — Post data-driven insights, trend analyses, or contrarian takes about your industry. Prospects in your target audience who engage with these posts become warm leads — they already know your name and value your perspective before you reach out.
Reposting Prospect Content as Pre-Outreach Engagement — Before sending a connection request, find and repost your target prospect's content with thoughtful commentary. This puts your name on their radar in a positive way. When your connection request arrives a few days later, they recognize you as someone who valued their work.
Building Social Proof for Your SDR Team — If you manage a team of SDRs, use Publishing to populate each SDR's LinkedIn profile with professional content. Prospects are more likely to accept invites from profiles that look active and credible, not from profiles with no posts and a generic headline.
Scheduling Content Around Campaign Launches — Time your content publishing to coincide with campaign launches. If you are running a campaign targeting VP-level prospects in SaaS, publish a post about SaaS industry trends 2-3 days before the campaign starts. This creates a natural context for your outreach.
Create Post — Detailed Guide:
Go to LinkedIn > Publishing in the sidebar
Select your LinkedIn account from the dropdown
Write your post content in the text area (maximum 3,000 characters)
Choose visibility: Public (recommended for outreach) or Connections Only
Optionally add an external link URL
Click 'Post' to publish immediately to your LinkedIn feed
Character Limit & Post Structure: LinkedIn allows up to 3,000 characters per post. However, longer does not always mean better. The most engaging posts are typically 800-1,500 characters — long enough to provide value, short enough to be consumed quickly. LinkedIn truncates posts after the first 2-3 lines with a 'see more' link, so your opening hook is critical. The first two lines must grab attention and compel the reader to expand the post.
What Makes a Good LinkedIn Post:
Start with a hook — a surprising statistic, bold claim, or relatable problem
Use short paragraphs (1-2 sentences) and line breaks for readability
Include a clear takeaway or actionable insight
End with a question or call-to-action to encourage comments
Write in first person — share your own experience, data, or perspective
Avoid generic advice — be specific and share real numbers when possible
Visibility Options — When to Use Each:
Public — Your post appears in LinkedIn search results, can be shared by anyone, and reaches the widest audience. Use Public for thought leadership content, industry insights, and any content designed to attract prospects outside your existing network. This is the recommended setting for outreach-related publishing.
Connections Only — Your post is visible only to your 1st-degree connections. Use this for more personal updates, internal announcements, or content that is only relevant to people who already know you.
External Links and LinkedIn Reach: LinkedIn algorithmically penalizes posts that contain external links in the body. Posts with external URLs typically receive 30-50% less reach compared to text-only posts. This is because LinkedIn wants users to stay on the platform. Best practice: write your post without any links, then add the link as the first comment after publishing. Alternatively, if you must include a link, use the dedicated link field in WarmySender — this creates a link preview card at the bottom of your post, which is slightly less penalized than an inline URL.
Content Ideas That Drive Engagement:
'How I did X' stories — Share a specific process that led to results
Industry data and benchmarks — 'We analyzed 10,000 cold emails and found...'
Contrarian takes — Challenge conventional wisdom with evidence
Lessons learned from failure — Vulnerability builds trust
Before/after comparisons — Show transformation with real numbers
Quick tips or frameworks — Actionable advice in list format
Commentary on industry news — Add your unique perspective
Customer success stories (with permission) — Social proof in narrative form
Repost Guide:
Switch to the 'Repost' tab in the Publishing page
Paste a LinkedIn post URL into the URL field
The system automatically extracts the post URN (unique resource name) and displays it for confirmation
Optionally add commentary — your own thoughts about the original post
Click 'Repost' to share it to your LinkedIn feed
How to Find Post URLs on LinkedIn: To get a post URL, click the three dots (...) menu on any LinkedIn post and select 'Copy link to post'. The URL will look like: https://www.linkedin.com/posts/username_activity-1234567890-xxxx or https://www.linkedin.com/feed/update/urn:li:activity:1234567890. Both formats are accepted by WarmySender.
Adding Commentary That Adds Value: A repost without commentary is essentially just a share — it adds minimal value and can look lazy. Always add your own perspective when reposting. Good commentary includes: why you found the post valuable, a related experience of your own, a respectful disagreement or additional nuance, or how the insight applies to your specific industry. Aim for 2-4 sentences of genuine commentary.
When to Repost vs. Create Original Content:
Repost when a prospect published something great and you want to put your name on their radar before connecting
Repost when an industry leader shared data relevant to your audience and you can add meaningful commentary
Create original content when you have your own insights, data, or experiences to share
Aim for a ratio of roughly 3 original posts for every 1 repost — too many reposts makes your profile look like you lack original ideas
URN Extraction Explained: When you paste a LinkedIn post URL, WarmySender extracts the URN (Uniform Resource Name) — LinkedIn's internal identifier for the post. This is the 'activity:1234567890' portion of the URL. The system validates this URN before allowing the repost. If the extraction fails, verify the URL is a direct link to a specific post (not a search result or profile page).
My Posts Dashboard:
The 'My Posts' tab shows all posts created through WarmySender with detailed engagement metrics:
Views (Impressions) — How many times your post appeared in feeds
Likes (Reactions) — Total reactions including likes, celebrates, supports, etc.
Comments — Number of comments on your post
Shares (Reposts) — How many people shared your post
Reading Engagement Metrics:
Engagement Rate — Calculate by dividing total engagements (likes + comments + shares) by impressions. A good LinkedIn post achieves 2-5% engagement rate. Above 5% is excellent.
Comments are the most valuable metric — they signal genuine interest and trigger LinkedIn's algorithm to show your post to more people.
High impressions but low engagement means your hook worked (people saw it) but the content did not compel action.
Low impressions usually means the first two lines were not compelling enough, or you posted at a suboptimal time.
When to Delete Underperforming Posts: Not every post will perform well — that is normal. Consider deleting posts that: received zero engagement after 48 hours, contain outdated information or broken links, no longer represent your current messaging or positioning, or attracted negative comments you cannot address constructively. However, do not delete too aggressively — an inconsistent posting history (gaps from deletions) can look worse than a few underperforming posts.
Tracking Content Performance Over Time: Use the My Posts dashboard to identify patterns in your content performance. Note which topics, formats, and posting times generate the most engagement. Over weeks and months, you will develop a clear picture of what resonates with your audience, allowing you to refine your content strategy for maximum impact on your outreach campaigns.
Engagement History:
The Engagement History tab shows your recent comments and reactions across LinkedIn, providing a centralized view of all your engagement activity.
Monitoring Your Comment and Reaction Activity: This tab displays every comment you posted and every reaction you left on other people's posts. Use this to: verify that engagement campaign steps executed correctly, ensure your comments are professional and on-brand, and track the volume of your engagement over time.
Using Engagement Data to Inform Outreach Timing: Your engagement history reveals when prospects are most active. If you commented on a prospect's post and they replied within an hour, that tells you they are active on LinkedIn at that time. Use this insight to time your connection requests and messages for when they are most likely to see and respond to them.
Best Practices & Content Strategy:
Post 2-3 times per week for optimal visibility — less than once a week and LinkedIn's algorithm forgets you; more than once a day and you risk audience fatigue
Use strong hooks in the first 2 lines — LinkedIn truncates your post with a 'see more' link, so the opening must compel readers to expand. Lead with a number, question, or bold statement
Avoid external links in the main post body — put links in the first comment instead. LinkedIn's algorithm reduces reach for posts with external URLs by 30-50%
Engage with comments on your posts within 1 hour — early engagement signals to LinkedIn's algorithm that the post is generating conversation, triggering wider distribution. Reply to every comment in the first hour
Best posting times are Tuesday through Thursday, 8-10 AM in your target audience's timezone — this is when LinkedIn professionals are most active. Monday mornings and Friday afternoons tend to underperform
Use line breaks generously — walls of text get scrolled past. Each paragraph should be 1-2 sentences maximum
End every post with a question — posts that end with a direct question receive 2-3x more comments than those that do not
Mix content types — alternate between how-to posts, personal stories, data insights, and opinion pieces to keep your feed interesting
Tag relevant people sparingly — tagging 1-2 people who would genuinely find the content relevant can expand reach, but tagging many people looks spammy
Do not use hashtags excessively — 3-5 relevant hashtags is the sweet spot. More than 5 makes your post look like spam and does not improve reach
Rate Limits & Account Safety:
WarmySender enforces conservative publishing limits to protect your LinkedIn account:
Reposts are limited to 5 per day per account — reposts are highly visible actions that LinkedIn monitors closely. Exceeding this limit may trigger LinkedIn's spam detection
Original posts follow LinkedIn's standard posting limits — there is no hard limit from LinkedIn, but posting more than 2-3 times per day is unusual behavior that could flag your account
Allow at least 2-3 hours between consecutive posts — rapid-fire posting looks automated
Commentary on reposts counts as content creation activity — factor this into your daily limits
If your account is new or recently reconnected, start with 1 post per day for the first week before increasing
All publishing activity respects the global daily action limits configured for your account
Publishing does not consume your messaging or connection request quotas — these are separate limits
Frequently Asked Questions:
Q: Can I schedule posts for later? A: Currently, posts are published immediately when you click 'Post' or 'Repost'. Scheduled publishing is on the roadmap. For now, plan your posting schedule manually and publish at your preferred times.
Q: Will publishing posts affect my connection request limits? A: No. Publishing and reposting use separate rate limits from connection requests, messages, and profile views. You can publish content without reducing your available outreach actions for the day.
Q: Can I edit a post after publishing? A: Post editing is not currently supported through WarmySender. To edit a published post, go directly to LinkedIn, find the post, click the three dots menu, and select 'Edit post'. The changes will be reflected in WarmySender's My Posts view.
Q: My repost failed — what went wrong? A: The most common causes are: the original post has been deleted by the author, the post is from a private profile you are not connected to, or the post URL was copied incorrectly. Verify the URL by opening it in your browser first. If the post loads correctly in your browser but still fails to repost, the post's author may have disabled resharing.
Q: How do I see who engaged with my posts? A: The My Posts dashboard shows aggregate metrics (total likes, comments, shares, views). To see the specific people who engaged, click on the post metrics directly on LinkedIn — WarmySender shows the counts, while LinkedIn shows the individual profiles.
Q: Should I use my personal LinkedIn account or a company page? A: WarmySender Publishing works with personal LinkedIn profiles, not company pages. This is intentional — personal profiles consistently outperform company pages in engagement and reach. Prospects connect with people, not logos. Use your personal profile for publishing and keep your company page for official announcements.
The Recruiting page in WarmySender lets you create, publish, and manage LinkedIn job postings, track applicants, download resumes, and oversee hiring projects — all from a single dashboard without switching between LinkedIn tabs.
Overview: LinkedIn Recruiting in WarmySender brings full job posting lifecycle management into your outreach platform. You can draft and publish job listings, monitor incoming applications, download candidate resumes, and close filled positions — all integrated alongside your LinkedIn campaigns, messaging, and analytics. This is especially powerful for teams that combine recruiting with sales prospecting, since you can manage both workflows from the same tool.
Use Cases:
Recruiting Agencies — Manage multiple job postings across different clients from one dashboard. Post jobs under different LinkedIn accounts (one per client), track applicants per role, and download resumes in bulk for client review. No need to log in and out of separate LinkedIn accounts.
Internal HR Teams — Corporate recruiters and HR departments can post open positions, track all applicants in one place, and coordinate hiring without giving every team member direct LinkedIn Recruiter access. The centralized view makes it easy to see all active postings and their applicant counts at a glance.
Staffing Firms — High-volume staffing agencies can post contract and temporary roles, quickly sort through applicants, and download resumes for candidate submissions. The sorting and filtering tools help you process large applicant pools efficiently.
Sales Teams Using Job Postings as Lead Magnets — A creative prospecting strategy: post job listings in your target market to attract decision-makers who view or apply. For example, posting a 'VP of Sales' role attracts sales leaders at companies you want to sell to. You gain visibility into who is actively looking, plus their contact details and resumes.
Recruiter Account Users — If you have a LinkedIn Recruiter subscription, WarmySender surfaces your hiring projects alongside job postings, giving you a unified view of your recruiting pipeline within your outreach tool.
Creating Job Postings — Detailed Guide:
Navigate to LinkedIn > Recruiting in the sidebar
Select the LinkedIn account you want to post from (each account posts independently)
Click 'Create Job' to open the job creation form
Fill in all required fields:
Job Title — The position name as it will appear on LinkedIn. Use specific, searchable titles (e.g., 'Senior React Developer' not 'Code Ninja'). LinkedIn's algorithm matches job titles to candidate searches, so standard industry titles perform better.
Company Name — The company offering the position. This should match an existing LinkedIn Company Page for best visibility. If the company page does not exist, LinkedIn will still accept the posting but it will not link to a company profile.
Workplace Type — Select On-site, Hybrid, or Remote. This is a required field and affects which candidates see your posting. Remote postings typically receive 2-3x more applicants.
Employment Type — Choose from Full-time, Part-time, Contract, Temporary, Internship, Volunteer, or Other. This helps candidates filter for roles that match their availability.
Location — The city, state, or region for the role. For remote positions, this often represents the company headquarters or the region where candidates must be eligible to work. Be specific to attract locally relevant candidates.
Job Description — The full description of the role, responsibilities, qualifications, and benefits. This is a free-text field that supports standard formatting.
Click 'Create' to save the job as a draft. Drafts are not visible on LinkedIn until you explicitly publish them.
Writing Effective Job Descriptions — Tips:
Lead with impact — Start with what the person will accomplish, not a company boilerplate paragraph. Candidates scan the first 2-3 lines to decide whether to read further.
Keep it concise — Aim for 1,000-2,000 characters. Descriptions over 2,000 characters get truncated on mobile devices, and most applicants browse LinkedIn on their phones.
Use bullet points for requirements — A bulleted list of 5-7 key qualifications is easier to scan than a paragraph. Separate 'must-have' from 'nice-to-have' requirements.
Include salary range — Postings with salary ranges receive up to 75% more applicants according to LinkedIn data.
Add a call to action — End with a clear next step: 'Apply now' or 'Send your resume and a brief note about your experience.'
Avoid jargon and internal titles — Use industry-standard terminology so your posting appears in candidate searches.
Draft vs. Published States:
Draft — The job is saved in WarmySender but not visible on LinkedIn. You can edit all fields freely. Use drafts to prepare postings in advance or get manager approval before publishing.
Published — The job is live on LinkedIn and visible to candidates. Applicants can find it through LinkedIn search, job alerts, and your company page. You can still close a published job at any time.
Publishing Jobs:
After creating a draft, click the 'Publish' button on the job card to make it live on LinkedIn.
Free Publishing — LinkedIn allows free job postings for most roles. WarmySender uses LinkedIn's free posting feature, so there is no additional cost for publishing through the platform. Free postings appear in LinkedIn search results and on your company page.
Checkpoint Verification — LinkedIn occasionally requires identity verification before allowing a job to be published. This typically happens when posting from a new account, posting in a new industry, or after a period of inactivity. When this occurs, WarmySender displays a verification dialog where you enter the code sent to your email or phone (OTP). Enter the verification code and click confirm to complete publishing.
What To Do If Verification Fails — If you do not receive the verification code, check your spam folder and ensure the email/phone on your LinkedIn account is current. You can request a new code by canceling and clicking Publish again. If verification continues to fail, log into LinkedIn directly in your browser to complete any pending security checks, then retry publishing from WarmySender. Persistent verification issues may indicate LinkedIn has flagged the account — contact support for assistance.
Managing Applicants:
Switch to the 'Applicants' tab on the Recruiting page
Select a published job from the dropdown to view its applicants
Use the sort options to organize your applicant list:
Newest First — Shows the most recent applicants at the top. Best for monitoring new applications daily.
Relevance — LinkedIn's algorithm ranks applicants by how well their profile matches the job requirements. Best for quickly finding top candidates in large applicant pools.
Alphabetical — Sorts by name (A-Z). Useful when searching for a specific applicant or when reviewing a short list.
4) Each applicant card displays:
Name — The candidate's full name as shown on their LinkedIn profile
Headline — Their LinkedIn headline (typically current role and company)
Rating — LinkedIn's match rating for the candidate based on skills and experience alignment
Email — The candidate's contact email if they provided one with their application
Profile URL — A direct link to their LinkedIn profile for detailed review
Downloading Resumes — Click the download button on any applicant card to save their resume as a PDF. This pulls the resume the candidate attached to their LinkedIn application. Not all applicants attach resumes — some apply with their LinkedIn profile only.
Best Practices for Reviewing Applicants:
Check applicants daily for active postings — fast response times improve your chances of landing top candidates.
Use the Relevance sort first to prioritize the strongest matches, then switch to Newest to catch recent applications.
Click through to the candidate's LinkedIn profile for a complete picture beyond their resume.
Download resumes promptly — if you close the job posting, applicant data may become less accessible over time.
Hiring Projects (Recruiter Only):
Hiring projects are a LinkedIn Recruiter feature that lets you organize your recruiting pipeline into structured projects, each tied to a specific role or search.
What Are Hiring Projects — A hiring project in LinkedIn Recruiter is a container for a specific search or role. It includes a pipeline of candidates at various stages (sourced, contacted, interviewed, etc.), plus associated job postings, notes, and team collaboration.
How They Relate to Job Postings — A hiring project can have one or more job postings attached to it. When you view a hiring project in WarmySender, you can see which job postings feed candidates into that project. This gives you a unified view: the job posting attracts inbound applicants, while the hiring project lets you manage both inbound and outbound (sourced) candidates in one pipeline.
Viewing Project Details — In WarmySender, switch to the 'Hiring Projects' tab (visible only for Recruiter accounts) to see a list of your active projects. Each project shows its name, associated job postings, and candidate counts. Click into a project to see its full pipeline and associated job postings.
Closing Jobs:
Close a job posting when the position has been filled, the posting has expired, or you no longer want to receive applications.
When to Close — Close promptly when you have selected a candidate to avoid wasting applicants' time. Also close if the role is put on hold, budget is cut, or the posting is underperforming and you want to rewrite it.
Confirmation Process — Clicking 'Close' on a published job triggers a confirmation dialog. You must confirm the action because closing is permanent — the job is removed from LinkedIn and will no longer appear in search results. Applicants who have already applied remain accessible, but no new applications will come in.
Best Practices:
Keep job descriptions concise — Under 2,000 characters performs best, especially for mobile readers. Long descriptions have higher drop-off rates.
Respond to applicants within 48 hours — Fast response times dramatically increase your chances of hiring top talent. Candidates who do not hear back within 48 hours often accept other offers.
Close filled positions promptly — Leaving filled jobs open wastes candidates' time and can hurt your employer brand. It also clutters your dashboard.
Use specific job titles — 'Senior Frontend Engineer (React)' outperforms 'Marketing Person' or 'Rockstar Developer'. Specific titles match better in LinkedIn search and attract qualified candidates.
Post during business hours — Jobs posted Tuesday through Thursday between 9 AM and 11 AM tend to get the most visibility in the first 24 hours.
Coordinate with your LinkedIn campaigns — If you are running outreach campaigns to the same audience, stagger job postings so you do not overwhelm prospects with multiple touchpoints at once.
Rate Limits:
LinkedIn limits job posting activity to protect against spam and abuse:
Maximum 2 job postings per day per LinkedIn account. This is a LinkedIn-enforced limit — attempting to exceed it will result in an error.
There is no limit on the number of draft jobs you can create. Drafts do not count against the daily publishing limit.
Applicant viewing and resume downloads are not rate-limited.
If you manage multiple LinkedIn accounts, each account has its own independent limit of 2 postings per day.
Frequently Asked Questions:
Q: Do I need LinkedIn Recruiter to use this feature? A: No. Job posting and applicant management work with any LinkedIn account, including free and Premium accounts. The Hiring Projects tab is the only feature that requires a LinkedIn Recruiter subscription.
Q: Are job postings free? A: Yes. WarmySender uses LinkedIn's free job posting feature. You can publish jobs at no additional cost beyond your WarmySender LinkedIn seat subscription. LinkedIn also offers paid 'Promoted' job listings directly on their platform, but WarmySender uses the free tier.
Q: Can I edit a job after publishing it? A: No. Once a job is published to LinkedIn, it cannot be edited through WarmySender. If you need to change the job details, close the current posting and create a new one with the updated information.
Q: Why am I not seeing any applicants? A: Applicants typically take 24-72 hours to start appearing for new postings. If you still see zero applicants after several days, check that the job was actually published (not still in draft), that the job title and description are searchable, and that the location is correct. Niche roles or overly specific requirements may receive fewer applicants.
Q: Can I post jobs to multiple LinkedIn accounts at the same time? A: Each job posting is tied to a single LinkedIn account. To post the same role from multiple accounts (e.g., for different regions), create separate job postings under each account. You can reuse the same title and description.
Proxy management lets you change the IP address used for your LinkedIn connection, improving account safety by matching your IP location to your LinkedIn profile's location.
Three Proxy Modes:
Auto — WarmySender automatically assigns a proxy that matches your account's location. Best for most users.
Country — Select a specific country from 22 available options. WarmySender uses a managed proxy in that country. Use this when your LinkedIn profile says you're in a specific country.
Custom — Enter your own proxy URL in the format: http://username:password@host:port. Supports HTTP, HTTPS, and SOCKS5 protocols. Use this if you have dedicated proxies.
How to Change Proxy:
Go to LinkedIn > Accounts
Click on an account to open details
Click 'Change Proxy' next to the current proxy display
Select your preferred mode and configure it
Click 'Save'
Important: Pause all active campaigns before changing your proxy. Switching proxies while campaigns are running may trigger LinkedIn's security systems. After changing the proxy, wait a few minutes before resuming campaigns.
WarmySender's 4 pillars — cold emailing, email warmup, LinkedIn outreach, and multichannel — all respect a campaign's sending window. This guide explains how the LinkedIn sending window works, why a small subset of LinkedIn campaigns occasionally queued sends outside the chosen hours before April 27, 2026, and how that issue is now resolved.
What the sending window is: Every campaign has four schedule controls: • Start hour — the earliest time of day (in your campaign's timezone) when sends are allowed (e.g., 9 AM) • End hour — the latest time of day when sends are allowed (e.g., 5 PM) • Schedule days — which days of the week sending is allowed (e.g., Mon/Tue/Wed/Thu/Fri) • Timezone — the IANA timezone (e.g., Asia/Kolkata, Europe/London, America/New_York) used to interpret the start/end hours
For example, a campaign set to 'Mon-Fri 9 AM to 5 PM Asia/Kolkata' will only send between 9 and 5 IST on weekdays. Outside those hours, the scheduler holds the job and clamps it forward to the next valid moment within the window.
Why sending only inside the window matters: LinkedIn's automation-detection systems weigh many signals. One of them is the time-of-day pattern of your account's activity. Per Unipile's published guidance (https://developer.unipile.com/docs/how-to-create-outreach-sequence), invitations and messages should be 'distributed on working days' at 'random intervals' — and Unipile assumes that 'working days' implies normal business hours. A connection request that fires at 4 AM looks unmistakably automated, even if the daily/weekly cap is respected. Sending strictly inside the user-configured window is therefore not just a UX preference — it is part of staying invisible to LinkedIn's automation detection.
The issue we found and fixed on April 27, 2026: WarmySender's scheduler runs both email and LinkedIn jobs through a single unified engine. The email branch of that engine has always called a function called `clampToSendingWindow` that re-aligns any job whose computed run-time falls outside the user's window. The LinkedIn branch was supposed to call the same function. Due to a copy-paste omission when the unified engine was first built, the LinkedIn branch only enforced the day-of-week (e.g., 'don't send on Saturday') but skipped the hour-clamp ('don't send before 9 AM or after 5 PM').
The practical impact: In the seven days leading up to the fix, roughly 134 LinkedIn jobs across the entire platform (about 0.6% of total LinkedIn jobs) queued at hours outside their campaign's chosen window. Most of these were a few hours off — a 5 PM cutoff that became a 6 PM send, or a 9 AM start that was nudged back to 8 AM by random jitter. The legacy LinkedIn-only scheduler enforced the window correctly, so older campaigns were unaffected. Campaigns sending within strict, narrow windows (e.g., London 10 AM-4 PM) were affected the most.
The fix: The LinkedIn branch of the unified scheduler now calls `clampToSendingWindow` immediately before every job is queued, identical to the email branch. We added a regression test that asserts every queued LinkedIn job's run-time falls within the campaign's window. No backfill is needed — historical sends already happened — but every send going forward will be inside your chosen hours.
How to verify your campaign respects your window:
Open your campaign in the LinkedIn dashboard.
Look at the schedule pill on the campaign card — it shows your active days and window in your timezone (e.g., 'Mon Tue Wed Thu Fri 9-17 IST').
Look at the 'next scheduled send' indicator on the campaign card. It should always show a time inside your window.
If you want to spot-check historical sends, open the campaign analytics tab and review the timestamps in the recent activity log.
What to do if you notice a send outside your window: It is very unlikely after April 27 — the regression test runs on every deploy. But if you do notice an out-of-window send, please email hello@warmysender.com with the campaign name, the date and time of the send, and the configured window. We will investigate the specific row.
Account safety always wins: Clamping a send forward into the window can never accelerate it. The scheduler only ever defers a job, never advances it past its earliest legal time. So this fix slightly reduces total daily volume on the affected campaigns; nothing about it increases LinkedIn API call volume. That is consistent with WarmySender's account-safety-first philosophy: every change must either reduce risk or keep it constant.
For the full LinkedIn safety model — invites, messages, InMails, profile views, ramp curves, and per-account caps — see the 'How LinkedIn account safety limits work' guide below.
WarmySender emits real-time webhook events for LinkedIn reply, invite acceptance, message sent, and account disconnect activity. This guide is the canonical reference for how the events flow, where to subscribe, how Slack and Discord messages are formatted, the n8n / generic JSON shape, how to test, how to troubleshoot, and why the webhook layer never affects LinkedIn account safety.
Supported events:
Four `linkedin.*` events are emitted today. All share the same envelope `{ event, id, occurredAt, workspaceId, data }` with HMAC-SHA256 signature on the body and a unique `X-Warmy-Event-Id` header for idempotency.
`linkedin.reply_received` — the prospect replied to a campaign message or InMail. Fired ONCE per enrollment on the first reply (subsequent messages on the same thread do not re-fire). Data fields: `campaignId`, `enrollmentId`, `prospectId`, `prospectName`, `prospectLinkedinUrl`, `linkedinAccountId`, `messageText` (the reply body, full length), `threadId`, `receivedAt`.
`linkedin.invite_accepted` — the prospect accepted a connection request. Fired ONCE per enrollment on the first acceptance (Unipile webhook retries do not duplicate). Data fields: `campaignId`, `enrollmentId`, `prospectId`, `prospectName`, `prospectLinkedinUrl`, `linkedinAccountId`, `acceptedAt`.
`linkedin.message_sent` — a campaign message or InMail successfully delivered (post-Unipile 2xx, post-counter-commit). Useful for CRM activity logging. Fired once per send, NOT once per step. Data fields: `campaignId`, `enrollmentId`, `prospectId`, `linkedinAccountId`, `messageType` ('message' | 'inmail'), `sentAt`.
`linkedin.account_disconnected` — the LinkedIn account auto-paused because the Unipile cookie expired or LinkedIn restricted the account. Useful for ops alerting. Data fields: `linkedinAccountId`, `accountName`, `disconnectedBy` ('user' | 'system' | 'linkedin'), `disconnectedAt`, `pausedCampaignIds` (array).
Open Settings → Webhooks (`/settings?tab=webhooks`).
Click 'New Webhook'. Paste your endpoint URL — Slack Incoming Webhook URL (https://hooks.slack.com/...), Discord Webhook URL (https://discord.com/api/webhooks/...), n8n / Make / Zapier HTTP Trigger URL, or your own HTTPS endpoint.
Pick events. For sales teams, the typical set is `linkedin.reply_received` + `linkedin.invite_accepted`. For ops, add `linkedin.account_disconnected`. Subscribe to `*` for everything.
Save. WarmySender returns a webhook secret — save it once (shown only on creation). Used for HMAC verification on your endpoint.
Click the new 'Test webhook' button on the webhook row. We fire a sample `linkedin.reply_received` payload to your URL through the real delivery path. Recent Deliveries shows the result.
The row now shows a 'Last fired' timestamp (`last_triggered_at`) updated on every successful delivery — useful for debugging silence (if it stops updating, the upstream signal is missing or the formatter is failing).
How Slack messages are formatted:
WarmySender auto-detects Slack Incoming Webhook URLs (host = `hooks.slack.com`) and formats events as Block Kit messages — no Zapier / Make / n8n middleware needed.
A `linkedin.reply_received` event arrives in Slack as a card with: - Header: 'New LinkedIn reply' with the WarmySender icon - Section block: prospect name (linked to LinkedIn profile) + campaign name (linked to campaign detail in WarmySender) + LinkedIn account that received the reply - Quoted block: the reply body (truncated to ~400 chars for readability; full body is in the JSON payload if you also subscribe via a generic endpoint) - Action buttons: 'Open in WarmySender' and 'View on LinkedIn' (deep links) - Context block: receivedAt timestamp in your workspace timezone
A `linkedin.invite_accepted` event arrives as: - Header: 'New connection accepted' - Section: prospect name (linked) + campaign name (linked) + 'Accepted at HH:MM YYYY-MM-DD' in workspace TZ - Action button: 'Send a message'
Formatting is server-side — Slack receives a JSON Block Kit body, NOT raw event JSON. If you point a non-Slack endpoint at a Slack URL by mistake, the formatter still runs because we route on URL host.
Discord support:
As of April 2026, Discord webhook URLs (host = `discord.com` / `discordapp.com`) are auto-detected and formatted as `{ content, embeds }` payloads. Each event becomes an embed with title, description (the reply body or 'X accepted Y's connection request'), color (blue for replies, green for acceptances, red for account_disconnected), and a pair of links in the description.
Before the formatter shipped, Discord webhook URLs received the raw JSON envelope and returned 400 Bad Request ('Cannot send an empty message') because Discord requires `content` or `embeds` at minimum. Old deliveries that hit that path are now in the dead-letter queue and are NOT auto-replayed (replay would fire stale notifications). If you need a backfill, contact support with the affected URL and date range.
Example Discord embed (linkedin.reply_received):
{ "content": null, "embeds": [{ "title": "New LinkedIn reply: Zoltan A. Vardy", "description": "\"Sounds good, send me the deck.\"\n\n[View in WarmySender](...) · [View on LinkedIn](...)", "color": 3447003, "timestamp": "2026-04-28T09:34:14.000Z", "footer": {"text": "Campaign: April Outreach · LinkedIn account: cyril@example.com"} }] }
n8n / generic:
Any URL that isn't recognized as Slack or Discord receives the raw signed JSON envelope. This includes n8n HTTP Trigger URLs, Make custom webhook URLs, Zapier Catch Hook URLs, AWS Lambda function URLs, and your own HTTPS endpoints.
Recommended n8n HTTP Trigger config: - Authentication: None (rely on HMAC verification — see the 'Webhooks — Getting Started' guide for the Node.js verification snippet). - Method: POST - Response Mode: Respond with response code 200 immediately, then process asynchronously (don't make WarmySender wait for downstream HubSpot / Slack calls — our retry timeout is 5 seconds). - Body: keep as JSON. The payload is `{ event, id, occurredAt, workspaceId, data }`. - Headers to capture: `X-Warmy-Event-Id` (idempotency key, store ~24 h), `X-Warmy-Signature` (parse `t=<unix_ms>,v1=<hmac_hex>`), `X-Warmy-Event-Type` (event name).
For Make / Zapier, the payload shape is identical; switch on `{{$json.event}}` to branch.
Testing your webhook:
On the webhook row in Settings → Webhooks, click the 'Test' button. We POST a sample `linkedin.reply_received` payload to your URL via the real delivery path (same signature, same retries, same dead-letter handling).
Check 'Recent Deliveries' on the same page — you'll see the response code and body within ~10 seconds.
If 2xx: your endpoint accepted the test; you should see the message in Slack / Discord / your n8n flow.
If 4xx: signature verification or formatting on your side rejected the payload; check the response body in Recent Deliveries for the error message.
If 5xx: your endpoint had a server error; we'll retry up to 10 times with exponential backoff (1 min → 72 h).
For real LinkedIn replies (not just the test button), the easiest end-to-end test is to reply to yourself from a second LinkedIn account or have a teammate reply.
Troubleshooting:
**'last_triggered_at' is not updating, but I know replies are coming in.** Two things to check. First, is the upstream signal arriving? Open Inbox → LinkedIn tab and confirm the reply is visible there. If yes, the inbound side is fine and the issue is in webhook emission — check Recent Deliveries for a 4xx/5xx, or contact support. Second, if the inbound side itself is empty, the issue is upstream of webhooks (Unipile cookie, account disconnected) and the webhook layer is correctly silent.
**Slack message arrives malformed (raw JSON instead of Block Kit).** Confirm the URL host is `hooks.slack.com`. URLs from `slack.com` or custom Slack domains are not auto-detected and fall through to the generic JSON path. Recreate the webhook with the canonical Incoming Webhook URL.
**Discord 'Cannot send an empty message' (400).** This was the pre-April 2026 bug. The Discord formatter now handles this. If you still see 400s after April 28, 2026, check Recent Deliveries for the actual response body — it may be a content-length mismatch on a Discord-hosted CDN attachment, which is unrelated to our formatter.
**Events array is missing on `linkedin.reply_received` / `linkedin.invite_accepted`.** Confirm the webhook is subscribed to the specific event. A webhook subscribed only to `*` (wildcard) will receive ALL events; one subscribed only to `linkedin.invite_accepted` will NOT receive replies. Check the webhook row's events list in Settings → Webhooks.
**Signature mismatch (401 from your endpoint).** You're hashing the parsed-then-reserialized JSON, not the raw body. Capture `req.rawBody` BEFORE `express.json()` (or equivalent middleware). Also confirm you're using the webhook secret, NOT the API key. Full Node.js snippet in the 'Webhooks — Getting Started' guide.
**Replies stopped firing entirely (platform-wide silence).** As of April 28, 2026 we run a cron monitor that compares inbound LinkedIn message volume against `linkedin.reply_received` emit volume every 3 hours; a >50% gap fires an internal alert. If you see a multi-day silence, contact support with the affected workspace ID and the date range.
Account safety note (CRITICAL):
Webhooks are read-side only. Receiving a webhook never triggers a LinkedIn API call. The emission path is: WarmySender DB row writes (post atomic UPDATE WHERE repliedAt IS NULL / WHERE acceptedAt IS NULL) → emit a webhook event row → deliverer pushes to your URL. No path from a webhook arrival back to Unipile. Subscribing to webhooks does not change polling cadence, daily caps, weekly caps, ramp pacing, or any LinkedIn action volume on your account. Every LinkedIn API call is driven by your campaign sends / invites / profile views, not by webhook activity. Account safety always wins over throughput, and webhooks live entirely on the safe side of that line.
For full HMAC signature verification, idempotency, retry schedule, and the rest of the cross-channel webhook reference (email events too), see the 'Webhooks — Getting Started' guide.
WarmySender automates the full outreach stack — cold emailing, email warmup, LinkedIn outreach, and multichannel sequences. On the LinkedIn side, account safety always wins over speed. A banned LinkedIn account is unrecoverable, so every cap below is set conservatively and is enforced by the scheduler regardless of how aggressively a campaign is configured. This guide explains the four cap dimensions, how they are computed, the four account types, the four ramp strategies, and the new dedicated InMail cap shipped on April 27, 2026.
The four cap dimensions WarmySender enforces per LinkedIn account:
Invites per week — How many connection requests the account can send in a rolling LinkedIn week. LinkedIn's own caps are 100-200 per week depending on tier. WarmySender stays at or below this ceiling.
Messages per day — How many direct messages to existing 1st-degree connections the account can send per day.
InMails per day (NEW April 27, 2026) — How many InMail messages to people who are NOT 1st-degree connections the account can send per day. Before April 27 this shared the messages-per-day bucket, which allowed up to 100 InMails per day on a Sales Navigator account — well above Unipile's recommended safe band of 30-50 per day. Now there is a dedicated cap, so InMails and regular messages are tracked and limited independently.
Profile views per day and engagements per day — How many profile views and how many post likes/comments/endorsements the account can make per day. These have always been capped per ramp week; no change in April 2026.
How the daily/weekly cap is computed: For each cap dimension, the effective limit is the MINIMUM of two values: • Account-type cap — A ceiling determined by your LinkedIn subscription tier (Free / Premium / Sales Navigator / Recruiter) • Strategy cap — A ramp-week-aware value determined by your account's ramp strategy (new_account / established / veteran / recovery)
The stricter of the two always wins. So a brand-new Recruiter account is held to the new_account ramp limits, not the Recruiter tier ceiling, until it has aged enough to graduate to a faster strategy.
The four ramp strategies (and what they mean):
new_account — 6-week ramp. Default for any account that is brand-new in WarmySender or that has no prior usage history. The most conservative strategy. Daily limits start at roughly 25-30% of full capacity in week 1 and reach full capacity around week 5-6.
established — 4-week ramp. Auto-applied to accounts that have been running clean in WarmySender for 30+ days. Faster ramp because we already have engagement data showing the account behaves naturally.
veteran — 2-week ramp. Auto-applied to accounts that have been running clean for 60+ days with no restrictions. Reaches full capacity within 2 weeks because the account has demonstrated it can handle higher volume.
recovery — 8-week ramp at half-speed. Auto-applied after any account restriction or ban event. The slowest, most conservative ramp. Designed to slowly rebuild trust with LinkedIn after a flagged event.
The four account types (and their ceilings):
Free — Standard LinkedIn. Cap: ~150 invites/week. InMails: not allowed (LinkedIn restricts InMail to paid tiers). Free accounts hit weekly caps fastest, especially with personalized invite notes.
The new InMail ramp curve in plain English (April 27, 2026):
If you connect a brand-new Sales Navigator account, you will start at 25 InMails per day in week 1. By week 2 you reach 40 InMails per day, which is the full capacity for a Sales Navigator veteran account. Premium accounts cap at 15 InMails per day even at full ramp. Free accounts cannot send InMails at all because LinkedIn restricts that feature to paid tiers.
The full ramp table (per strategy) for InMails per day:
new_account week 1-2: 15 per day
new_account week 3+: 25 per day
established: 35 per day
veteran: 40 per day (the center of Unipile's safe 30-50 band)
recovery: 10 per day
These values are then capped by the account-type ceiling above. So a brand-new Sales Navigator account is held at 25/day in week 3 (strategy cap), even though Sales Navigator's account-type ceiling is 50/day. A veteran Premium account is held at 15/day (account-type cap), even though the veteran strategy would allow 40/day.
Why we ramp gradually (the most important paragraph):
Unipile is WarmySender's official LinkedIn integration partner. Their published safe daily band for InMails (https://developer.unipile.com/docs/provider-limits-and-restrictions) is 30-50 per day across all paid tiers. Going faster than that — even on a Recruiter account that LinkedIn technically allows up to 100/day — significantly increases the chance that LinkedIn flags your account for unusual activity and applies a temporary restriction. A restriction can range from a 'verify your identity' challenge (24-48 hour resolution) to a permanent account loss. WarmySender's default of 40/day for a Sales Navigator veteran sits comfortably in the middle of Unipile's safe band, and the 2-week ramp from 25 to 40 mirrors the natural growth pattern of a real human user.
How to override (custom override field in account settings):
If you have legitimate operational need to push higher than the default — for example, a Recruiter account with a documented LinkedIn-Recruiter contract allowing 100/day — you can set a custom override per account. The fields are:
customMaxInvitesPerWeek
customMaxMessagesPerDay
customMaxInmailsPerDay (new April 27, 2026)
customRampWeeks (override the strategy ramp length)
These fields are validated server-side: the override cannot exceed Unipile's published safe ceiling (e.g., InMails cannot be set above 50/day even with an override, regardless of LinkedIn's stated upper bound). The override must be set explicitly per account from the LinkedIn Account settings page, and changing it requires acknowledging the risk warning. We deliberately do NOT expose a 'turn off all safety limits' option, because that would put your account in the high-risk band without recourse.
How to check your current limits:
Go to LinkedIn > Accounts in the sidebar.
Click into a specific account.
The account detail panel shows: account type pill (Free / Premium / Sales Navigator / Recruiter), current strategy (new_account / established / veteran / recovery), current ramp week (e.g., 'Week 3 of 6'), and the four effective daily/weekly caps for invites, messages, InMails, profile views, and engagements.
Below that, you can see today's running counts toward each cap (e.g., 'Invites this week: 47/200 — 30% of cap'). When a cap is reached, the next scheduler tick stops queuing that action type until the cap window resets.
What happens when a cap is reached:
The scheduler does not 'overflow' or 'burst' to catch up. Each campaign sharing the account simply waits until the cap resets — daily caps reset at 00:00 UTC, weekly caps roll on Monday 00:00 UTC. Prospects in flight do not lose their place in the sequence. They wait at their current step until the next legal sending opportunity. This is consistent with the 'never bulk-replay missed sends after an outage' principle: bursting is the single most reliable way to trigger LinkedIn restrictions, so we always pace at the configured rate, not a catch-up rate.
What happens if user config conflicts with safety limits:
If a campaign is set to 'send 100 invites per day' but the per-account cap is 40, the campaign will execute 40 invites per day until the prospect pool is exhausted or the account graduates to a higher cap. The campaign does NOT fail, and prospects do NOT silently disappear — they wait. This is the 'account safety always wins' rule from CLAUDE.md: when user intent conflicts with safety, safety wins and the step waits or defers.
Summary table of full-ramp caps (after the strategy ramp completes):
The strategy cap is then applied on top — for example, a Sales Navigator veteran account hits 40 InMails/day even though the account-type ceiling is 50/day, because the veteran strategy caps at 40 (the center of Unipile's safe band).
For more on Unipile's published guidance, see https://developer.unipile.com/docs/provider-limits-and-restrictions. For the related sending-window enforcement fix shipped the same day, see the 'Why my LinkedIn campaign sometimes sends outside my chosen hours' guide above.
Prospects are your campaign contacts, managed from the Prospects page:
Global Statuses:
Active — Available for campaigns
Bounced — Email bounced (automatically set)
Invalid — Email address is invalid
Unsubscribed — Prospect opted out
Do Not Contact (DNC) — Manually marked, blocks all outreach
Suppressed — Blocked by suppression list
Adding Prospects:
CSV Import — Upload a CSV file with column mapping (see CSV Import guide)
Paste Data — Paste tab or comma-delimited data directly
Single Add — Manual form entry with all fields
From Leads Database — Save leads from the built-in 20M+ contact database
From LinkedIn — Import from LinkedIn audience enrichment
Prospect Lists: Organize contacts into named lists with custom colors. Each list tracks its prospect count. Use lists to: • Segment contacts by industry, role, or campaign • Create campaigns from specific lists • Keep imported batches organized
Bulk Operations:
Select multiple prospects using checkboxes (or 'Select All')
Bulk delete (with active campaign guard — can't delete prospects in active campaigns)
Bulk status update (change global status)
Bulk add to prospect list
Bulk add to campaign
Filtering & Search:
Text search across email, first/last name, and company
Filter by global status
Filter by prospect list (sidebar)
Pagination with configurable page size
Each prospect also has per-campaign statuses: new, contacted, replied (positive/neutral/negative), bounced, unsubscribed, DNC — these are tracked independently for each campaign the prospect is enrolled in.
The Contacts section provides a CRM-style view of people you have interacted with across your campaigns.
Accessing Contacts: Go to Contacts from the sidebar to view your contact list.
Contacts vs. Prospects: Prospects are people you plan to reach out to — they are your campaign targets. Contacts are people you have already interacted with, whether through email replies, LinkedIn conversations, or manual outreach. When a prospect replies to a campaign or engages with your LinkedIn messages, they become a contact with a full interaction history.
Viewing Contact Details: Click on any contact to see their full profile including: • Contact information (email, phone, company, role, location) • Interaction history — every email sent and received, LinkedIn messages, and campaign touchpoints • Campaign enrollment history — which campaigns they were part of and their status in each • Notes and tags added by your team
Filtering & Searching:
Search by name, email, company, or any contact field
Filter by interaction type (email reply, LinkedIn reply, manual)
Filter by campaign or prospect list
Sort by most recent interaction, name, or company
Use the Contacts view to manage ongoing relationships and follow up with engaged prospects outside of automated campaign sequences.
Custom fields: use prefix custom: (e.g., custom:department, custom:source)
Auto Column Mapping: The system automatically maps common column name variations: • 'e-mail', 'e_mail' → email • 'first name', 'first_name' → firstName • 'last name', 'last_name' → lastName • 'company name', 'company_name' → company • 'title', 'job_title', 'position' → role • 'telephone', 'mobile' → phone • 'linkedin', 'linkedin_url', 'linkedin_profile' → linkedinUrl
You can also manually map any column during the import wizard.
Validation & Deduplication:
Email format validation (must be valid format)
MX DNS validation (domain must have valid mail server)
Dedup by email within the file and against existing workspace prospects
LinkedIn URL dedup for LinkedIn-only rows
Suppression list check (both email-level and domain-level)
LinkedIn-Only Rows: If a row has no valid email but has a LinkedIn URL, a placeholder email (li.username@noemail.warmysender.com) is generated so the prospect can exist in the system.
Custom Fields: Any CSV column not matching a built-in field is stored as a custom field. Field names are sanitized: lowercased, non-alphanumeric characters replaced with underscores, max 30 characters.
Using Custom Columns as Merge Tags: Every custom column you import becomes a merge tag you can use in your campaign emails — including in the subject line. For example, a column custom:icebreaker becomes {{custom.icebreaker}} or {{icebreaker}} in your templates. This lets you send fully pre-written, personalized emails where every part is unique per prospect.
Import Progress:
Large imports run asynchronously — you can close the page and come back
Progress bar shows processed rows, created, duplicates, invalid, and suppressed counts
Maximum 10,000 rows per import
Example CSV: email,firstName,lastName,company,role,phone,linkedinUrl,website,country,city,industry,custom:department john@acme.com,John,Smith,Acme Corp,VP Sales,+1234567890,linkedin.com/in/johnsmith,acme.com,US,New York,Technology,Engineering
The Leads Database contains 20M+ verified B2B contacts from the US and Canada:
Data Sources & Coverage: Our B2B leads database is compiled from multiple reliable and publicly available sources, including verified business directories, government registries, and public filings. The data is sourced independently and enriched through multiple verification passes to ensure quality.
Geographic Coverage:
United States — 9M+ business contacts across all 50 states
Canada — 160K+ business contacts across all provinces
Other regions are not currently available
Industry & Sector Coverage: The database covers a wide range of B2B sectors and industries including: • Professional Services, Technology/SaaS, Healthcare, Construction, Legal • Restaurants & Food Service, Real Estate, Financial Services, Manufacturing • Retail, Education, Nonprofits, Government Contractors, and many more • Use the Category and Industry filters to search within your target sector
Phone Numbers: Phone numbers in our database are business phone numbers sourced from directory listings and public filings. We do not provide personal mobile or cell phone numbers.
Data Accuracy & Freshness:
Lead data is enriched from multiple sources and cross-referenced for accuracy
The database is continuously updated with new imports and enrichment passes
Use the 'Has Email' filter (on by default) to see only leads with email addresses
Use the Email Verifier before launching campaigns to ensure maximum deliverability
Accessing Leads:
Go to Leads from the sidebar
Available on Pro ($14.99) plans and above
Free plans see an upgrade prompt
Search Filters:
Keyword — Matches name, company, email, industry, and description
Country — Dropdown selector (cascading: resets state/category when changed)
Category — Business category (e.g., Restaurant, Plumber, SaaS)
State / Province — Geographic filter
City — Free text city filter
Has Email — Show only leads with email addresses (ON by default)
Has Phone — Show only leads with phone numbers
Lead Data Available:
Contact info: name, email, business phone, job title
Company info: business name, website, employee count, revenue range, industry
WarmySender includes a built-in Email Verifier to validate email addresses before campaigns — reducing bounces and protecting sender reputation. Included free with all paid subscription plans.
Free trial, Starter, and Lifetime plans: Not available (upgrade to Pro+)
Monthly usage resets on the 1st of each month (UTC)
How It Works: The verifier performs real SMTP handshake verification — it connects to the recipient's mail server and checks if the mailbox exists, without actually sending any email. This is the same technique used by professional tools like ZeroBounce and NeverBounce, included free with your plan.
The verification process: 1. Checks email format validity 2. Looks up the domain's MX (mail server) records 3. Connects to the mail server on port 25 4. Performs EHLO handshake 5. Tests if the recipient address is accepted (RCPT TO) 6. Checks if the domain is a catch-all (accepts any address) 7. Disconnects — no email is ever sent
Accessing the Email Verifier: Navigate to Email > Email Verifier in the sidebar (look for the green 'New' badge). You'll see three tabs:
--- Tab 1: Batch Verification (CSV Upload) --- Verify a list of email addresses from a CSV file.
How to use: 1. Click 'Upload CSV' and select your file 2. The system automatically detects the email column (supported headers: email, email_address, e-mail, contact_email, emailaddress) 3. If no header matches, the system checks each column for email-formatted values 4. Emails are deduplicated, validated, and sanitized before processing 5. Verification processes gradually in the background (not all at once) to ensure accuracy and avoid rate limits 6. Monitor progress with the real-time progress bar — the page auto-refreshes every 3 seconds 7. View results filtered by status (All, Valid, Invalid, Risky, Unknown) 8. Download the complete results as a CSV when finished
CSV Requirements:
File must contain an 'email' column (or similar header name)
Maximum 100,000 emails per batch
Maximum 10MB file size
Supports: quoted fields with commas (RFC 4180), UTF-8 with BOM (Excel exports), Windows/Mac/Unix line endings
Duplicate emails within the file are automatically removed
--- Tab 2: Verify a List --- Verify emails directly from your existing prospect lists — no CSV export/import needed.
How to use: 1. Select a prospect list from the dropdown 2. Click 'Verify List' 3. The system extracts all email addresses from the list's prospects (skips prospects without emails and LinkedIn-only placeholders) 4. Verification runs in the background with real-time progress 5. When complete, two things happen automatically: a) A NEW list called '[Your List Name] - Verified' is created containing only prospects with valid or risky emails b) Prospects with invalid emails are automatically marked as 'invalid' in your database (globalStatus updated) 6. The verified list appears in your Prospects page ready to use in campaigns
This is the recommended workflow before launching any campaign: 1. Import your prospects into a list 2. Go to Email Verifier > Verify a List 3. Select the list and verify 4. Use the auto-created '[Name] - Verified' list in your campaign
--- Tab 3: Single Check --- Verify a single email address instantly.
How to use: 1. Enter an email address in the input field 2. Click 'Verify' or press Enter 3. See instant results: status, MX host, catch-all detection, and response time 4. Rate limited to 20 verifications per minute per workspace
Verification Statuses:
Valid — The email address exists and can receive mail. Safe to send. Shown with a green badge.
Invalid — The email address does not exist, the mailbox is full, the domain has no mail server, or it's a known disposable email. Do not send. Shown with a red badge.
Risky — The domain is a 'catch-all' that accepts all addresses (e.g., small companies using Google Workspace catch-all). The email probably works but cannot be confirmed. Send with caution. Shown with a yellow badge.
Unknown — The mail server temporarily refused the check (greylisting, rate limiting, or server timeout). Not invalid — try again later. Shown with a gray badge.
Catch-All Domains Explained: Some domains are configured to accept emails sent to any address (e.g., anything@company.com works). When the verifier detects this, it marks the email as 'risky' because it cannot confirm the specific mailbox exists. About 15-20% of B2B domains are catch-all. These emails are usually deliverable, but bounces are possible.
Batch Management:
All your verification batches are listed in the left panel with status indicators
Click any batch to see detailed results on the right
Filter results by status using the filter buttons
Download completed batches as CSV (available for 1 day after completion)
Cancel in-progress batches — pending verifications are stopped immediately
Your monthly usage is shown in the page header ('X / Y used this month')
Monthly Usage:
Displayed in the header as a badge: 'X / Y used this month'
Counts all emails submitted for verification (CSV uploads + list verifications)
Resets on the 1st of each month (UTC)
If you hit your limit, uploads and list verifications are blocked with a clear message showing your usage
Single email checks are rate-limited separately (20/min) but do not count against the monthly limit
Prospect Limits by Plan: Each plan has a maximum number of prospects you can store: • Pro: 10,000 prospects • Business: 100,000 prospects • Enterprise: 300,000 prospects • Existing prospects are never deleted on plan changes — you just cannot add new ones if you're over the limit
Data Retention:
Verification results CSV files are stored for 1 day, then automatically deleted
Batch records and individual results remain in the database indefinitely for your reference
Verified prospect lists (created from 'Verify a List') are permanent and behave like any other prospect list
Best Practices:
Always verify email lists before launching a campaign — this is the single most effective way to prevent high bounce rates
Use 'Verify a List' instead of CSV upload when your contacts are already in WarmySender — it's faster and automatically creates a clean list
Remove or exclude invalid addresses before sending — the 'Verify a List' feature does this automatically
Re-verify lists that are more than 30 days old, as email addresses can become invalid over time
Use the verifier after importing from external sources (purchased lists, scraped data, etc.)
Combine with Bounce Shield for maximum deliverability protection
For catch-all domains (marked as 'risky'), the email likely exists but cannot be confirmed — include them in campaigns but monitor bounce rates
Start with a small test batch if you're verifying a large purchased list — check the valid rate before committing your full monthly quota
FAQ: Q: Does the verifier send any emails? A: No. It only performs an SMTP handshake (connection + RCPT TO check) without sending any message data.
Q: Will verification affect my sender reputation? A: No. The verification is performed from a separate dedicated server, not from your connected mailboxes.
Q: Why are some results 'Unknown'? A: Some mail servers temporarily refuse verification attempts (greylisting, rate limiting). This does not mean the email is invalid. Try again later or include them in your campaign with caution.
Q: What happens to invalid prospects when I use 'Verify a List'? A: They are automatically marked with status 'invalid' in your prospect database. They remain in the original list but will be skipped by campaigns that filter by status.
Q: Can I re-verify the same list? A: Yes. Each verification creates a new batch and a new verified list. This is useful for re-checking lists after 30+ days.
Q: Do single email checks count toward my monthly limit? A: No. Single checks have a separate rate limit (20/minute) but do not deduct from your monthly verification quota.
Clean data is the foundation of successful outreach. Poor data quality causes bounces, spam complaints, and reputation damage.
Why Data Hygiene Matters:
Bounce rates above 3% damage your sender reputation.
Invalid emails waste your daily sending quota.
Outdated contacts result in spam complaints (people at new companies).
Duplicate records cause embarrassing double-sends.
Before Importing (Pre-Import Cleaning):
Remove obvious junk — blank rows, test entries, personal emails (gmail.com, yahoo.com for B2B campaigns).
Standardize formatting — consistent name capitalization, remove extra spaces.
Verify email format — every email must contain @ and a valid domain.
Remove role-based emails — info@, sales@, support@, admin@ have high bounce and complaint rates.
Check for suppressed domains — remove emails from domains on your blocklist.
Using WarmySender's Built-in Tools:
Email Verifier — Verify all imported emails before sending. Status: Valid, Invalid, Risky, Unknown.
MX Validation — During import, emails with invalid domain DNS are automatically flagged.
Deduplication — Import automatically skips duplicates (by email within your workspace).
Suppression List — Matches against your blocklist during import.
Ongoing Maintenance:
Re-verify lists older than 30 days — email addresses go stale at ~2% per month.
Review bounced contacts monthly — remove or re-verify them.
Monitor your bounce rate in Analytics. If it exceeds 3%, clean your lists immediately.
Export your suppression list periodically and cross-reference with active prospect lists.
Remove prospects who have been contacted 3+ times with no engagement.
Bounce Shield Integration: Enable Bounce Shield in Settings to automatically: • Pause campaigns when bounce rates exceed your threshold. • Add bounced addresses to your suppression list. • Alert you via email when issues are detected.
Best Practices:
Verify before you send — always. It costs far less than reputation damage.
Custom fields let you store additional prospect data beyond the built-in fields and use them for personalization.
How Custom Fields Work: When you import a CSV with columns that do not match built-in field names (email, firstName, lastName, company, role, phone, linkedinUrl, website, country, city, industry), they are stored as custom fields.
Creating Custom Fields: 1) Add extra columns to your CSV with a 'custom:' prefix header: custom:department, custom:pain_point, custom:referral_source, custom:product_interest 2) During import, these columns are automatically detected and stored. 3) Field names are sanitized: lowercased, non-alphanumeric characters replaced with underscores, max 30 characters.
Using Custom Fields in Emails:
Reference them with the custom prefix: {{custom.department}}, {{custom.pain_point}}, {{custom.referral_source}}
The bare shorthand also works: {{department}}, {{pain_point}} (as long as it doesn't conflict with a built-in field name)
Use with fallback values: {{custom.pain_point | default: 'scaling your outreach'}}
Combine with built-in tags: 'Hi {{firstName}}, as head of {{custom.department}} at {{company}}...'
Popular Custom Field Ideas:
Pain point — Pre-research their specific challenge.
Mutual connection — 'We both know {{mutual_connection}}'.
WarmySender uses first-touch attribution for all campaign revenue reporting on the admin dashboard.
When you click a link to WarmySender — from an ad, an email, a social post, or a referral — we record the source the very first time you arrive at the site. That first source stays with your account for 90 days, even if you leave and come back.
Concretely:
First click: You land on warmysender.com from Campaign A. We set a secure, http-only cookie (named ws_attrib) that records Campaign A as your source. The cookie is host-scoped, sameSite=lax, and lasts 90 days.
Later visits: You leave, then come back days or weeks later from a different ad (Campaign B). We do NOT overwrite Campaign A — the first signal wins. Campaign B is recorded as a separate "paid-touch" signal but does not move revenue between buckets.
Signup and payment: Whenever you eventually sign up (email magic-link, Google sign-in, or Apple sign-in) and pay, the revenue is attributed to Campaign A on /admin/stats.
Why first-touch? It tells us which campaigns introduce customers to the product, which is what marketing budget actually paid for. Last-touch attribution rewards retargeting (which often just shows the ad to someone who already decided to buy), while first-touch rewards genuine acquisition.
How we keep this evergreen across signup paths:
All three signup paths — email magic-link, Google OAuth, and Apple OAuth — read the same first-touch ws_attrib cookie and persist the captured UTM source/medium/campaign to the user record at signup. The cookie always wins over per-click signals (OAuth state, request body, URL params), because per-click signals are latest-touch leaks by definition. If the cookie is missing (private browsing, ad blocker, old browser without cookies), we fall back to the URL parameters at click time. Attribution data is never silently overwritten on a return visit.
What's tracked:
The first-touch capture includes utm_source, utm_medium, utm_campaign, gclid (Google Ads), fbclid (Meta Ads), the original referrer URL, and the timestamp of first touch. Google Ads gclid auto-derives to (google, cpc) if no explicit UTM is set; Meta fbclid auto-derives to (facebook, paid_social).
First-touch vs paid-touch:
We also record a separate paid_utm_source/medium/campaign snapshot at the moment of first checkout. Both signals are kept on the user record:
signup_utm_* — the campaign that introduced the user (first-touch, used for revenue attribution)
paid_utm_* — the most recent campaign before purchase (last-touch, kept for divergence analysis only)
The admin dashboard surfaces an "Attribution Health" panel showing coverage percentage, paid users without attribution, and the first-touch≠paid-touch divergence rate so we can monitor the integrity of the data over time.
Warmup — Active mailboxes, average success rate, emails warmed today, average health score. Per-mailbox status table with level badge, daily progress, success rate.
Date Range: 7 days, 14 days, 30 days (default), 90 days. Channel Filter: All / Email / LinkedIn. CSV Export: Download analytics data as CSV for external analysis.
Key Benchmarks:
Open Rate: Aim for 40%+ (below 20% = improve subject lines)
WarmySender supports multi-user workspaces for team collaboration:
What is a Workspace? • A workspace is an isolated environment containing its own mailboxes, campaigns, prospects, templates, analytics, and settings • When you sign up, one workspace is automatically created for your account • Your subscription plan (Pro, Business, Enterprise) covers your entire account — all workspaces you own share your plan's email quota • LinkedIn seats are billed separately per workspace ($9/seat/month per workspace)
Multiple Workspaces:
Business plan: Up to 3 workspaces
Enterprise plan: Up to 5 workspaces
Pro plan: 1 workspace (upgrade to Business for more)
Each workspace is completely isolated: separate mailboxes, campaigns, prospects, LinkedIn accounts, templates, and analytics
Your plan's monthly email quota (e.g., 10,000/month on Pro) is shared across all workspaces you own
LinkedIn seats are per-workspace — each workspace that uses LinkedIn needs its own seats
Use the workspace switcher in the sidebar to switch between your workspaces
Creating Additional Workspaces (Business & Enterprise): 1) Click the workspace switcher in the sidebar 2) Click 'Create Workspace' at the bottom of the dropdown 3) Enter a name for your new workspace 4) Your new workspace is created and becomes your active workspace • Each additional workspace starts empty — connect mailboxes, import prospects, and set up campaigns separately • No extra charge — additional workspaces are included with your Business or Enterprise plan • Pro users: Upgrade to Business ($29.99/month) to unlock multiple workspaces
Roles & Permissions:
Owner — Full access including billing and workspace deletion. Cannot be removed.
Admin — Manage mailboxes, campaigns, members. Access all features except billing.
User — Create campaigns, manage prospects, view analytics. Shown as 'Member' in the workspace switcher.
Readonly — View-only access. Cannot modify any data. Shown as 'Viewer' in the workspace switcher.
Team Member Limits by Plan:
Free / Lite: 1 member
Pro: 2 members (owner + 1 invited)
Business / Enterprise: 4 members (owner + 3 invited)
Dominate / Rampage (legacy): Unlimited
Inviting Team Members:
Go to Settings > Team tab
Click 'Invite' (disabled when at plan limit — pending invites count toward limit)
Enter the invitee's email address and select a role (Admin or User)
They receive an email with a secure invitation link
They click the link, log in (or create an account), and accept the invitation
They're added to your workspace with the assigned role
Pending Invitations:
Visible in the Team tab with email, role, expiry date, and inviter
Can be canceled before acceptance
Invitations have an expiry period
Workspace Switching:
If you belong to multiple workspaces, use the workspace switcher in the sidebar
Click on a workspace name to switch — all data (mailboxes, campaigns, prospects, etc.) switches to that workspace
Each workspace has independent data and settings
Shared Resources:
All team members share mailboxes, campaigns, prospects, templates, and analytics within a workspace
If you downgrade to a plan with fewer workspace slots (e.g., Business to Pro), your existing workspaces are NOT deleted
You keep full access to all existing workspaces — you can still switch between them, run campaigns, and manage data
You simply cannot create new workspaces beyond your new plan's limit
All workspaces will operate under your new plan's sending limits (e.g., Pro's 10,000 emails/month shared across all workspaces)
Mailboxes vs. Team Members (Important Distinction):
Mailboxes are email accounts you connect (e.g., john@acme.com, sales@acme.com). All paid plans include UNLIMITED mailboxes — there is no cap.
Team members are people who log in to your workspace to manage campaigns. Each member gets their own login and role.
Connecting a mailbox does NOT require a team member seat. A single workspace owner can connect and manage 10, 50, or 500 mailboxes alone — no additional seats needed.
Example: You have 6 domains with 3 email accounts each (18 mailboxes total). You can connect all 18 to one workspace on the Pro plan ($14.99/month) and manage them yourself — no team members required.
Team member seats are only needed when other people need their own login to help manage your workspace.
Common Use Cases for Multiple Workspaces:
Agency managing outreach for multiple clients — one workspace per client
Business with multiple brands or product lines
Separating sales outreach from partnership outreach
Keeping test/sandbox campaigns separate from production
Toggle between monthly and annual on the Billing page
How the limited-time 40% annual offer works:
The 40% discount is evergreen but framed with a real end-of-month deadline that resets monthly — the date you see is the actual end of this calendar month UTC, but the discount itself does not actually disappear when the date hits.
Existing annual subscribers (pre-2026-04-29) keep their original 25% price — they are grandfathered at the rate they signed up for.
Promo codes can stack on top of the 40% (a 10% off code at checkout makes the total ~46% off list).
LinkedIn seats are unaffected — they remain monthly-only at $9/seat/month.
All Paid Plans Include:
Unlimited connected mailboxes on all paid plans (Free: 1, Lite: 3)
Email warmup (A.H.D.E. algorithm)
Multi-step sequences
A-Z testing (26 variants)
Unified inbox
Team collaboration
Analytics dashboard
Custom tracking domains
Bounce Shield protection
API & webhook access
LinkedIn Seats (Add-On):
Requires an active paid subscription (any paid plan)
Available as an add-on at $9/month per seat
Each seat allows one connected LinkedIn account
Minimum 1, maximum 10 seats per workspace
Manage seats from the Billing page (add, reduce, or cancel)
Can be bundled with a plan during initial checkout
Important: If your main subscription is canceled or becomes inactive, all LinkedIn accounts will be disconnected and LinkedIn campaigns will be paused. Canceling only the LinkedIn add-on does NOT affect your email plan.
Billing with Multiple Workspaces:
Your subscription (Pro, Business, or Enterprise) is account-level — it covers all workspaces you own
Your monthly email quota is shared across all your workspaces (e.g., 10,000 emails/month on Pro is the total across all workspaces)
LinkedIn seats are billed separately per workspace — each workspace that uses LinkedIn needs its own seat subscription
Team member limits apply per workspace (e.g., Pro allows 2 members per workspace)
Business/Enterprise: Create additional workspaces from the workspace switcher — no extra subscription charge
Billing Management:
Upgrade or downgrade anytime — changes take effect immediately
Payment processed securely via Stripe
View billing history and download invoices
Update payment method
Cancel subscription (access continues until period end)
For refund requests, see our Refund Policy at /refund-policy
Subscription Statuses:
Active — Paid and current
Past Due — Payment failed (soft warning)
Canceled — Will end at period end
Inactive — Subscription ended (restricted to billing page only)
When your subscription becomes inactive, active campaigns are automatically paused. They auto-resume when you re-subscribe.
Suppression lists prevent emails from being sent to specific addresses or domains:
Managing Your Blocklist: 1) Go to Settings > Blocklist tab 2) Add entries by type: • Email suppression — Block a specific email address (e.g., john@competitor.com) • Domain suppression — Block an entire domain (e.g., competitor.com blocks all @competitor.com addresses) 3) Each entry can have an optional reason for tracking
Automatic Suppression:
Bounced emails are auto-added (source: 'bounce')
Unsubscribed prospects are auto-added (source: 'unsubscribe')
Spam complaints are auto-added (source: 'complaint')
Manual entries show source: 'manual'
Enforcement:
During CSV import: any email matching a suppression entry is automatically skipped and counted as 'suppressed'
During campaign sending: suppressed prospects are blocked from receiving emails
Domain-level suppression matches all emails at that domain
Case-insensitive matching
CAN-SPAM Compliance:
Every campaign email includes an unsubscribe link in the footer
RFC-compliant List-Unsubscribe and List-Unsubscribe-Post headers
Unsubscribe requests are processed immediately
Physical address should be included in your email footer
GDPR Compliance:
Respect opt-out requests promptly
Maintain your suppression list as your 'do not contact' registry
Consider adding a privacy policy link to your email footer
Data access and deletion requests should be handled through your workspace settings
Best Practice: Regularly review and clean your suppression list. Add competitor domains, existing customer domains, and known bad addresses proactively.
Email authentication records are DNS settings that prove you are authorized to send email from your domain. Setting up all three is critical for inbox placement.
SPF (Sender Policy Framework):
Specifies which mail servers can send email on behalf of your domain
DNS record type: TXT record on your root domain
Example: v=spf1 include:_spf.google.com ~all
Check with your email provider for the correct 'include' value
DKIM (DomainKeys Identified Mail):
Adds a cryptographic signature to your emails to verify they haven't been tampered with
DNS record type: TXT or CNAME record (provider-specific subdomain)
Your email provider generates the DKIM key — check their documentation
Set up a custom tracking domain for better email deliverability:
Why Custom Tracking Domains:
Default tracking uses WarmySender's shared domain for open/click tracking
A custom domain (e.g., track.yourdomain.com) improves deliverability because the tracking links match your sending domain
Email providers are less likely to flag emails with matching domains as suspicious
Setup Steps: 1) Go to Settings > Tracking Domains 2) Click 'Add Domain' and enter your tracking subdomain (e.g., track.yourdomain.com) 3) The system shows the CNAME target you need to add: track.warmysender.com 4) Go to your DNS provider and create a CNAME record: - Name/Host: track (or your chosen subdomain) - Value/Target: track.warmysender.com - TTL: 3600 (or default) 5) Wait for DNS propagation (can take up to 48 hours, usually faster) 6) Click 'Verify' in WarmySender to confirm the CNAME is resolving correctly
Status Values:
Pending — CNAME record not yet verified
Verified — CNAME confirmed, tracking active through your domain
Error/Failed — CNAME not found or misconfigured
You can set up multiple tracking domains. Tracking domains are managed per workspace.
Best Practice: Use a subdomain of your sending domain (e.g., if you send from @acme.com, use track.acme.com).
WarmySender monitors bounce rates across your recent sends
When the bounce rate within the configured window exceeds your threshold, Bounce Shield activates
If auto-pause is enabled, affected campaigns are paused to prevent further damage
If auto-blocklist is enabled, bounced addresses are added to your suppression list
You receive an email notification (if enabled)
This is in addition to the per-campaign safety metrics (5% bounce rate threshold with 50 minimum sends). Bounce Shield provides workspace-level protection across all campaigns.
Best Practice: Keep the default settings. Lower the threshold to 5% if you are very cautious about deliverability. Verify your email lists before importing to reduce bounces.
WarmySender provides a REST API and webhook system for integrations:
API Keys (Settings > API Keys): 1) Click 'Create Key' and give it a name 2) Select scopes (permissions) for the key: • Prospects: read / write • Mailboxes: read / write • Warmup: read / write • Campaigns: read / write (create, update, start, pause) • Enrollments: write • Suppressions: read / write • Webhooks: read / write • Jobs: read 3) The full key is shown ONCE on creation — copy and save it securely 4) After creation, only the key prefix is stored (for identification)
Authentication:
Use the header: Authorization: Bearer YOUR_API_KEY
Keys are hashed with SHA-256 for storage security
Keys can have an expiration date
Revoke keys anytime from the API Keys tab
Webhooks (Settings > Webhooks): 1) Click 'Create Webhook' and enter your endpoint URL 2) Select which events to subscribe to: • reply.received — A prospect replied to a campaign email • email.bounced — An email hard-bounced • email.unsubscribed — A prospect clicked the unsubscribe link • email.opened — A prospect opened a campaign email • email.clicked — A prospect clicked a tracked link • prospect.suppressed — A prospect was added to the suppression list • limit.hit — A daily sending limit was reached 3) Each webhook gets a unique secret for signature verification 4) Test your endpoint with the 'Test' button
Webhook Delivery:
Events are delivered via HTTP POST to your endpoint
Signed with HMAC-SHA256 (X-Warmy-Signature header)
Failed deliveries are retried up to 10 times with exponential backoff
Delivery history is tracked per webhook
For full API reference, visit warmysender.com/docs/integrations
WarmySender includes guided tours to help you get started:
Main Onboarding Tour:
Automatically shown to new users after selecting a plan
Step-by-step walkthrough of the main features
Can be skipped at any time
Replay anytime from Settings > Account > Product Tour > 'Replay Onboarding Tour'
Page-Specific Tours:
First time visiting key pages (Campaigns, Mailboxes, etc.), a contextual tour explains that page's features
Each page tour is shown once and marked as completed
Reset all page tours from Settings > Account > Product Tour > 'Reset Page Tours'
Nurture Email Sequence: • New unpaid users receive a 5-day email sequence with tips: - Day 1: Welcome and inbox placement overview - Day 2: Quick win — set up 2 mailboxes - Day 3: Common mistakes to avoid - Day 4: Warmup → then launch workflow - Day 5: Final tips and encouragement • Sequence stops automatically when you upgrade to a paid plan • Sends daily at 8 AM PST
Best Practice: Complete the full onboarding tour to understand all features. If you feel lost at any point, replay the tour from Settings.
Set up webhooks to integrate WarmySender with your CRM and automation tools.
What Are Webhooks? Webhooks are real-time HTTP notifications sent from WarmySender to your endpoint whenever specific events occur (reply received, bounced, unsubscribed, etc.).
Setup (5 minutes):
Go to Settings > Webhooks.
Click 'Create Webhook'.
Enter your endpoint URL (where WarmySender sends the event data).
Select which events to subscribe to.
Copy the webhook secret for signature verification.
Click 'Test' to send a test event and verify your endpoint.
Available Events:
reply.received — Triggered when a prospect replies to a campaign email.
email.bounced — Triggered when an email hard-bounces.
email.unsubscribed — Triggered when a prospect clicks the unsubscribe link.
email.opened — Triggered when a prospect opens a campaign email (first open per campaign).
email.clicked — Triggered when a prospect clicks a tracked link (first click per link per day).
prospect.suppressed — Triggered when a prospect is added to the suppression list.
limit.hit — Triggered when a daily sending limit is reached (mailbox, domain, or plan).
Payload Format: Each webhook delivers a signed JSON payload via HTTP POST: { 'type': 'reply.received', 'data': { 'prospectId': '...', 'prospectEmail': 'john@acme.com', 'campaignId': '...', 'receivedAt': '2026-03-15T10:30:00Z' }, 'timestamp': '2026-03-15T10:30:00Z' }
Security Headers:
X-Warmy-Signature — HMAC-SHA256 signature for payload verification.
X-Warmy-Event-Type — The event type (e.g., reply.received).
X-Warmy-Event-Id — Unique event ID for deduplication.
Integration Examples:
CRM Sync (HubSpot, Salesforce, Pipedrive):
Subscribe to reply.received and email.bounced events.
On reply: create or update a CRM contact, log the interaction, create a task for follow-up.
On bounce: update contact status to invalid.
Slack/Teams Notifications:
Subscribe to reply.received.
Post to a sales channel when a prospect replies for real-time team awareness.
Zapier / Make / n8n:
Use these automation platforms as your webhook endpoint.
Create workflows that trigger actions in any of 5,000+ apps.
Example: Reply received → Create HubSpot deal → Notify Slack → Add to Google Sheet.
Retry Policy: Failed deliveries (non-200 responses) are retried up to 10 times with exponential backoff (1min, 5min, 15min, 1hr, 3hr, 6hr, 12hr, 24hr, 48hr, 72hr). Check delivery history in Settings > Webhooks.
Best Practice: Start with reply.received — it is the highest-value event for sales teams. Add more events as your integration matures.
Get started with the WarmySender REST API in 5 minutes.
Step 1: Create an API Key • Go to Settings > API Keys. • Click 'Create Key' and name it (e.g., 'My CRM Integration'). • Select scopes: choose read/write permissions for the resources you need. • Copy and save the full API key — it is shown only once.
Step 2: Make Your First Request All API requests use the base URL: https://warmysender.com/api/v1 Authenticate with the header: Authorization: Bearer YOUR_API_KEY
Example — List Your Prospects: GET /api/v1/prospects Returns a paginated list of prospects in your workspace.
Example — Add a Prospect: POST /api/v1/prospects Body: { 'email': 'john@acme.com', 'firstName': 'John', 'company': 'Acme' }
Example — List Campaigns: GET /api/v1/campaigns Returns all campaigns with status, stats, and configuration.
Step 3: Handle Responses • Success: 200 OK with JSON response body. • Created: 201 Created for POST requests. • Error: 400 (bad request), 401 (unauthorized), 403 (forbidden scope), 404 (not found), 429 (rate limited). • Rate limits: 60 requests per minute per API key.
Common Use Cases:
Create and manage campaigns programmatically.
Sync prospects from your CRM to WarmySender.
Pull campaign analytics into your dashboard.
Programmatically manage suppression lists.
Automate prospect enrollment into campaigns.
Start/pause campaigns based on external triggers.
Full API Reference: Visit warmysender.com/docs/integrations for complete endpoint documentation with request/response examples, error codes, and webhook setup.
Best Practices:
Use read-only scopes when you only need to pull data.
Store API keys securely — never commit them to code repositories.
Set expiration dates on keys used for temporary integrations.
Handle rate limit responses (429) with exponential backoff.
Use webhooks for real-time events instead of polling the API.
Complete reference for all webhook event types, payloads, and deduplication behavior.
8 Event Types Available:
1) reply.received Fires when a prospect replies to a campaign email (first reply only). Payload: prospectId, prospectEmail, campaignId, mailboxId, subject, messageId, receivedAt Dedup: One event per prospect per campaign (ever).
2) email.bounced Fires when an email hard-bounces (permanent delivery failure). Payload: prospectId, prospectEmail, campaignId, mailboxId, bounceType (hard/soft), bounceReason, bouncedAt Dedup: One event per prospect per campaign per day.
3) email.unsubscribed Fires when a prospect clicks the unsubscribe link. Payload: prospectId, prospectEmail, campaignId, unsubscribedAt Dedup: One event per prospect per campaign (ever).
4) email.opened Fires when a prospect opens a campaign email (tracked via invisible pixel). Payload: prospectId, prospectEmail, campaignId, mailboxId, stepIndex, openedAt Dedup: One event per prospect per campaign (first open only). Subsequent opens by the same prospect do not trigger additional events. Note: Some email clients (Apple Mail, Outlook) may auto-load images, causing false opens. Use clicks for more reliable engagement tracking.
5) email.clicked Fires when a prospect clicks a tracked link in a campaign email. Payload: prospectId, prospectEmail, campaignId, mailboxId, stepIndex, url, clickedAt Dedup: One event per unique URL per prospect per day. If a prospect clicks Link A and Link B, you receive two separate events. Clicking the same link twice on the same day fires only once.
6) prospect.suppressed Fires when a prospect is added to the suppression list (via unsubscribe, bounce, or manual suppression). Payload: prospectId (optional), email, reason, suppressedAt Dedup: One event per email per day.
7) limit.hit Fires when a daily sending limit is reached. Payload: limitType (daily_mailbox or daily_domain), mailboxId, campaignId, currentValue, limitValue, hitAt Dedup: One event per limit type per identifier per day.
8) webhook.test Fires when you send a test event via the API (POST /api/v1/webhooks/:id/test) or by clicking 'Test' in Settings > Webhooks. Payload: webhookId, timestamp, message Dedup: None — each test generates a unique event. Used to verify your endpoint is reachable and correctly processing events.
How to verify webhook signatures to ensure events are from WarmySender.
Why Verify Signatures? Without verification, anyone who discovers your endpoint URL could send fake events. Signature verification ensures only WarmySender can send valid events.
How It Works:
When you create a webhook, you receive a secret (format: whsec_xxxx). Save it securely.
Every webhook delivery includes an X-Warmy-Signature header.
The header format is: t=<timestamp>,v1=<hex_signature>
To verify, reconstruct the signature using your secret and compare.
Verification Steps:
Step 1: Extract timestamp and signature from X-Warmy-Signature header:
Understanding and monitoring your domain's sender reputation.
What Is Domain Reputation? Email providers (Gmail, Outlook, Yahoo) assign a reputation score to every sending domain based on engagement, complaints, and bounces. High reputation = inbox placement. Low reputation = spam folder.
Monitoring in WarmySender:
Analytics > Mailboxes — SPF, DKIM, DMARC check status per domain.
Analytics > Deliverability — Inbox rate trends, domain health matrix.
Warmup > Per-mailbox health scores — Real-time sender reputation per mailbox.
External Monitoring Tools (Recommended):
Google Postmaster Tools — Free. Shows your domain reputation as seen by Gmail (High, Medium, Low, Bad). Set up at postmaster.google.com.
Microsoft SNDS — Shows your IP reputation with Outlook/Hotmail.
MXToolbox — Check if your domain is on any email blocklists.
Mail-tester.com — Send a test email and get a spam score.
Reputation Factors:
Bounce rate — High bounces signal bad list quality. Keep below 3%.
Spam complaints — Recipient-reported spam is the strongest negative signal.
Engagement — Opens and replies boost reputation. Ignored emails lower it.
Volume consistency — Sudden spikes in volume look suspicious.
Authentication — SPF, DKIM, DMARC all properly configured.
Content quality — Spam trigger words, excessive links, or HTML reduce trust.
Improving Reputation:
Verify email lists before sending (use Email Verifier).
Warm up properly — do not skip the 2-3 week warmup period.
Start campaigns with low volume (20-30/day) and increase gradually.
Monitor bounce rates and stop campaigns immediately if above 5%.
Keep warmup running in Maintenance mode alongside campaigns.
Remove non-engaging prospects after 3-4 touchpoints.
Ensure DNS records are complete and valid.
Recovery from Bad Reputation: • If your domain reputation drops to Low or Bad: 1) Pause all campaigns immediately. 2) Run warmup only in Recovery mode for 2-4 weeks. 3) Verify and clean all prospect lists. 4) Review email content for spam triggers. 5) Resume campaigns at very low volume once health recovers above 70. • Severe damage may take 4-8 weeks to recover from. • If a domain is permanently flagged, consider retiring it and warming up a new secondary domain.
WarmySender sends real-time webhook notifications for key events: email replies, LinkedIn replies (with the reply body), LinkedIn invite acceptances, bounces, unsubscribes, opens, clicks, and sending-limit alerts. This guide is the canonical reference — specific integrations (Slack, n8n, HubSpot, etc.) link back here.
Event Catalog:
reply.received — Prospect replied to a campaign email. Payload: prospectId, prospectEmail, campaignId, sequenceId, mailboxId, subject, messageId, receivedAt, channel.
linkedin.reply_received — Prospect replied to a LinkedIn message or InMail. Payload: prospectId, prospectName, prospectLinkedinUrl, campaignId, enrollmentId, linkedinAccountId, messageText (the reply body, up to ~400 chars for Slack / full length in JSON), threadId, receivedAt.
webhook.test — Fired by the test button in Settings for endpoint verification.
All events use the same envelope: { type, data, timestamp }.
Creating a Webhook:
Settings → Webhooks → New webhook.
Paste your endpoint URL. Slack Incoming Webhook URLs (https://hooks.slack.com/…) are auto-formatted as Block Kit messages — see the 'Slack Notifications' guide. Everything else receives the signed JSON payload.
Pick events. Start with reply.received + linkedin.reply_received + linkedin.invite_accepted for sales teams; add email.bounced + limit.hit for ops.
Save. WarmySender returns a webhook secret — save it somewhere secure, you'll need it to verify signatures. The secret is shown once.
Click the test button on the webhook row to send a webhook.test event end-to-end. You should receive a POST within ~10 seconds.
Signature Verification (HMAC-SHA256): Every delivery includes these headers: • X-Warmy-Event-Id — unique event UUID (use for idempotency on your side) • X-Warmy-Event-Type — e.g., linkedin.reply_received • X-Warmy-Signature — combined Stripe-style format: t=<unix_ms>,v1=<hmac_hex>. The canonical timestamp lives inside this header — parse v1= out before comparing, and use the parsed t= for the HMAC input. (X-Warmy-Timestamp is also sent as a separate header for convenience/logging but the canonical copy is inside X-Warmy-Signature.) • Content-Type: application/json
The HMAC input is the string `${t}.${rawBody}` signed with your webhook secret using SHA-256.
Verify in Node.js (Express). Two common pitfalls: (1) reading X-Warmy-Signature as raw hex — it isn't, parse v1= first. (2) comparing against re-serialized JSON — key order, whitespace, and unicode escaping won't byte-match what we signed. Always capture the RAW request body before json parsing.
const crypto = require('crypto'); // Capture raw body BEFORE express.json(): // app.use(express.json({ verify: (req, _r, buf) => { req.rawBody = buf.toString('utf8'); } })); app.post('/webhook', (req, res) => { const sigHeader = req.headers['x-warmy-signature'] || ''; const parts = Object.fromEntries(sigHeader.split(',').map(p => p.split('='))); const ts = parts.t; const sig = parts.v1; if (!ts || !sig) return res.sendStatus(400); if (Math.abs(Date.now() - parseInt(ts, 10)) > 5 * 60 * 1000) return res.sendStatus(401); // 5-min replay guard const expected = crypto.createHmac('sha256', WEBHOOK_SECRET).update(ts + '.' + req.rawBody).digest('hex'); const a = Buffer.from(sig, 'hex'); const b = Buffer.from(expected, 'hex'); if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.sendStatus(401); // signature valid — process the event res.sendStatus(200); });
Skipping verification is acceptable on a private network (self-hosted n8n on a VPN). Always verify when the endpoint is publicly reachable.
Idempotency & Deduplication: Delivery is at-least-once — the same event may be delivered more than once due to retries or network races. Use the X-Warmy-Event-Id header as your dedupe key (store it in a database or cache for ~24 h).
For LinkedIn events, we dedupe at the source (per-enrollment for replies, per-acceptance for invites) so Unipile webhook retries don't cause duplicate emissions. Your endpoint still needs its own dedupe as defense in depth.
First-Reply Semantics (linkedin.reply_received): This event fires once per enrollment when the prospect first responds. Subsequent messages in the same thread do NOT re-fire (same semantics as campaigns auto-pausing on first reply). If you need every inbound message on a thread (not just the first reply), the webhook event catalog above isn't sufficient — please contact support to discuss options; this isn't currently exposed as a standalone event.
Retry Schedule: On any non-2xx response or 5-second timeout, we retry up to 10 times with exponential backoff: 1 min → 5 min → 15 min → 1 h → 3 h → 6 h → 12 h → 24 h → 48 h → 72 h. Honor Retry-After on HTTP 429 — we parse both seconds and HTTP-date formats, capped at our max backoff. After 10 failed attempts, the delivery is marked failed and the webhook's failure count is incremented.
Account Safety (LinkedIn Events): WarmySender's webhook delivery does not make any LinkedIn API calls on your behalf — events are emitted from our database state only (post atomic WHERE repliedAt IS NULL / WHERE acceptedAt IS NULL guards, so Unipile retries don't cause duplicate events or extra work). Toggling webhooks on or off doesn't change how often we poll LinkedIn via Unipile; your LinkedIn account's daily action limits are driven by campaign sends / invites / profile views, not by webhook activity.
Testing:
Use the test button in Settings → Webhooks for an end-to-end sanity check (fires webhook.test via the real delivery path).
For ad-hoc testing of a specific event, use tools like RequestBin or webhook.site to inspect the payload shape before wiring to your production endpoint.
LinkedIn event testing: reply to yourself from a test LinkedIn account (or have a teammate reply) and watch Settings → Webhooks → Recent Deliveries.
Troubleshooting:
Signature mismatch → check you're hashing the raw body, not the parsed-then-reserialized JSON; check you're using the webhook secret, not the API key.
No delivery when expected → confirm you're subscribed to the right event type; check Recent Deliveries in Settings for 4xx/5xx responses.
Test button returns 200 but nothing arrives → your endpoint is returning 200 without actually doing anything, or the event got filtered; check Recent Deliveries for the test event.
LinkedIn reply event not firing → only the FIRST reply per enrollment emits; subsequent messages in the same thread don't re-fire by design.
Related Guides: 'Slack Notifications' (native, no middleware), 'n8n Integration', 'Zapier Integration', 'Make Integration', 'HubSpot CRM Integration'.
Connect WarmySender to HubSpot CRM to automatically sync prospect activity and campaign data.
What This Integration Does:
Automatically create or update HubSpot contacts when prospects reply, open, or click.
Log campaign activity (emails sent, opens, clicks, replies) as timeline events on HubSpot contact records.
Create deals or tasks in HubSpot when a prospect replies to your campaign.
Keep your suppression list in sync — bounced or unsubscribed contacts are flagged in HubSpot.
Setup Option 1: Direct Webhook (Recommended)
Step 1: Create a webhook handler Build a simple endpoint on your server (or use a serverless function like AWS Lambda, Vercel, or Cloudflare Workers) that receives WarmySender webhook events and calls the HubSpot API.
Step 2: Configure the webhook in WarmySender • Go to Settings > Webhooks > Create Webhook. • Enter your handler endpoint URL. • Subscribe to events: reply.received, email.opened, email.clicked, email.bounced, email.unsubscribed. • Save and copy the webhook secret for signature verification.
Step 3: Map events to HubSpot actions In your webhook handler, call the HubSpot API based on the event type: • reply.received → Create/update contact, create a deal, log a note: POST /crm/v3/objects/contacts (HubSpot API) • email.opened → Update contact property 'last_engagement_date', log timeline event • email.clicked → Update contact property, log the clicked URL as a note • email.bounced → Set contact property 'email_status' to 'invalid' • email.unsubscribed → Set contact property 'hs_email_optout' to true
Step 4: Test Click 'Test' in WarmySender webhook settings. Verify the test event reaches your handler and creates a record in HubSpot.
Setup Option 2: Via Zapier (No Code) See the 'Zapier Integration' guide below for a no-code approach using Zapier as the middleware between WarmySender webhooks and HubSpot.
HubSpot API Reference:
Contacts API: POST /crm/v3/objects/contacts
Deals API: POST /crm/v3/objects/deals
Notes API: POST /crm/v3/objects/notes
Authentication: Use a HubSpot Private App token (Bearer auth).
Best Practices:
Use HubSpot's 'upsert' (createOrUpdate) to avoid duplicate contacts — match by email.
Map WarmySender prospectId to a custom HubSpot property for traceability.
Log the campaign name and step index in HubSpot notes for context.
Set up HubSpot workflows to auto-assign deals to sales reps when a reply is received.
Connect WarmySender to Salesforce to sync campaign activity and create leads automatically.
What This Integration Does:
Create Salesforce Leads or Contacts when prospects reply to your campaigns.
Log email opens, clicks, and replies as Activities on the Lead/Contact record.
Update Lead Status when emails bounce or prospects unsubscribe.
Create Opportunities when high-intent actions are detected (e.g., link clicks, replies).
Setup Option 1: Direct Webhook
Step 1: Create a middleware endpoint Build a handler (AWS Lambda, Heroku, etc.) that translates WarmySender webhook events into Salesforce API calls.
Step 2: Configure the webhook • Go to Settings > Webhooks > Create Webhook. • Enter your middleware endpoint URL. • Subscribe to: reply.received, email.opened, email.clicked, email.bounced, email.unsubscribed.
Step 3: Map events to Salesforce objects • reply.received → Upsert Lead (match by email), create Task ('Follow up — prospect replied'), update Lead Status to 'Contacted' • email.opened → Create Activity (Subject: 'Email Opened — [Campaign Name]') • email.clicked → Create Activity with the clicked URL, update Lead Score • email.bounced → Update Lead Status to 'Bad Email' • email.unsubscribed → Update Lead Status to 'Unsubscribed', set Email Opt Out = true
Step 4: Salesforce authentication Use Salesforce Connected App with OAuth 2.0 (JWT Bearer flow for server-to-server). Store your Salesforce access token securely.
Setup Option 2: Via Zapier or Make See the Zapier or Make integration guides for a no-code approach.
Salesforce API Endpoints:
Create Lead: POST /services/data/v59.0/sobjects/Lead
Create Task: POST /services/data/v59.0/sobjects/Task
Upsert by external ID: PATCH /services/data/v59.0/sobjects/Lead/Email__c/{email}
Best Practices:
Use External ID fields (email) for upsert to avoid duplicate records.
Create a custom Salesforce field 'WarmySender_Campaign_ID' for attribution.
Use Salesforce Process Builder or Flow to auto-assign leads to the right rep based on territory.
Log all WarmySender events as Activities for a complete timeline view.
Connect WarmySender to 7,000+ apps using Zapier — no code required.
How It Works: Zapier acts as a bridge between WarmySender webhooks and any app Zapier supports (HubSpot, Salesforce, Slack, Google Sheets, Airtable, Gmail, Notion, and thousands more).
Step-by-Step Setup:
Step 1: Create a Zap in Zapier • Log in to zapier.com and click 'Create Zap'. • For the trigger, choose 'Webhooks by Zapier'. • Select trigger event: 'Catch Hook'. • Zapier generates a unique webhook URL — copy it.
Step 2: Register the webhook in WarmySender • Go to Settings > Webhooks > Create Webhook. • Paste the Zapier webhook URL. • Select which events to subscribe to (e.g., reply.received, email.clicked). • Save the webhook.
Step 3: Send a test event • Click 'Test' in WarmySender webhook settings. • Go back to Zapier and click 'Test Trigger' — it should find the test event. • Zapier will show you the payload structure.
Step 4: Add an action Choose what happens when the event fires. Popular actions: • HubSpot: Create/Update Contact • Salesforce: Create Lead • Google Sheets: Create Spreadsheet Row • Slack: Send Channel Message • Pipedrive: Create Person/Deal • Gmail: Send Email (internal notification) • Airtable: Create Record • Notion: Create Database Item
Step 5: Map fields Map WarmySender webhook fields to your action app: • data.prospectEmail → Contact Email • data.prospectId → External ID • data.campaignId → Source Campaign • type → Event Type
Step 6: Test and enable Test the full Zap, then turn it on. Events from WarmySender will automatically trigger your action.
Popular Zap Recipes:
Reply received → Create HubSpot deal + Notify Slack channel
Email bounced → Update Google Sheet row + Remove from Mailchimp list
Link clicked → Create Pipedrive activity + Send Slack DM to sales rep
Prospect suppressed → Update Airtable record
Tips:
Use Zapier's 'Filter' step to only trigger actions for specific campaign IDs or event types.
Use 'Formatter' to transform data (dates, text) before sending to the destination app.
Enable 'Autoreplay' so failed Zaps are automatically retried.
Use multi-step Zaps to chain actions (e.g., create contact → create deal → send notification).
Connect WarmySender to 1,500+ apps using Make (formerly Integromat) for advanced automation workflows.
Why Make: Make offers more complex branching, filtering, and data transformation than Zapier — ideal for multi-step automation with conditional logic.
Step-by-Step Setup:
Step 1: Create a new Scenario in Make • Log in to make.com and click 'Create a new Scenario'. • Add a trigger module: search for 'Webhooks' and select 'Custom webhook'. • Click 'Add' to create a new webhook — Make generates a unique URL. Copy it.
Step 2: Register in WarmySender • Go to Settings > Webhooks > Create Webhook. • Paste the Make webhook URL. • Subscribe to your desired events. • Click 'Test' to send a sample event.
Step 3: Determine data structure • Go back to Make and click 'Redetermine data structure' on the webhook module. • It will detect the WarmySender payload fields automatically.
Step 4: Add action modules Connect modules for your destination app: • Router module — Branch based on event type (reply.received → one path, email.bounced → another). • HubSpot module — Create/Update Contact, Create Deal. • Google Sheets module — Add Row. • Slack module — Send Message. • HTTP module — Call any API.
Step 5: Add filters and routing Make excels at conditional routing: • Route 1: If type = 'reply.received' → Create CRM deal + Notify Slack • Route 2: If type = 'email.bounced' → Update CRM status + Log to sheet • Route 3: If type = 'email.clicked' → Score lead + Create task
Step 6: Enable the scenario Set the scheduling to 'Immediately' (webhook-triggered). Toggle the scenario on.
Advanced Features:
Data stores — Keep a local database in Make for deduplication and lookups.
Iterators — Process multiple items from a single webhook (e.g., batch events).
Error handlers — Add fallback routes for failed operations.
Aggregators — Collect multiple events and send a daily summary.
Best Practices:
Use Make's built-in 'JSON' module to parse the webhook payload if auto-detection fails.
Add error handlers to every critical module to prevent scenario failures.
Use data stores to track which prospects have already been synced to avoid duplicates.
Set up email notifications for scenario errors in Make's settings.
Connect WarmySender to n8n, the open-source workflow automation tool, to fan out events (email replies, LinkedIn replies, invite acceptances, bounces) into any downstream system — CRM, databases, Slack, Teams, Discord, Sheets, custom APIs.
Why n8n:
Self-hosted — your data stays on your infrastructure.
No per-task pricing — unlimited executions.
400+ integrations with a visual workflow builder.
Ideal for teams with privacy requirements or high automation volume.
Setup:
Step 1: Create a Webhook trigger in n8n • Open your n8n instance and create a new workflow. • Add a 'Webhook' node as the trigger (under Core Nodes). • Set HTTP Method to POST. • Set Response Mode to 'Immediately' (we need a 200 within 5 seconds — our timeout). • Activate the workflow and copy the Production URL (NOT the Test URL — test URLs expire).
Step 2: Register in WarmySender • Settings → Webhooks → New webhook. • Paste the n8n Production URL. • Subscribe to desired events (see list below). • Save and click the test button to confirm delivery.
Step 3: Route by event type Add a Switch node after the Webhook trigger, routing on {{ $json.type }}: • reply.received — Email campaign reply • linkedin.reply_received — LinkedIn message / InMail reply (includes reply body in messageText) • linkedin.invite_accepted — LinkedIn connection request accepted • email.bounced — Hard bounce • email.unsubscribed — Unsubscribe link clicked • email.opened / email.clicked — Open / link click (high volume) • prospect.suppressed — Prospect added to suppression list • limit.hit — Daily sending limit reached • webhook.test — Test event fired from Settings
Step 4: Add downstream actions Example chains (from real customer setups):
1) LinkedIn reply → Slack + HubSpot task: Webhook → IF (type = linkedin.reply_received) → Slack node (post to #sales-replies with {{ $json.data.messageText }}) → HubSpot node (Create Task: 'Follow up on LinkedIn reply').
2) Every reply → Google Sheets log: Webhook → IF (type contains 'reply') → Google Sheets 'Append Row' (Timestamp, Channel, Prospect, Campaign, Body).
3) Invite accepted → Pipedrive deal: Webhook → IF (type = linkedin.invite_accepted) → Pipedrive node (Create Deal in 'Connected' stage, mapped from {{ $json.data.prospectLinkedinUrl }}).
4) Per-campaign routing to different Slack channels: Webhook → Switch (by {{ $json.data.campaignId }}) → multiple Slack outputs, one per channel.
5) Bounce log + ops alert: Webhook → IF (type = email.bounced) → Postgres Insert → Microsoft Teams node.
Signature Verification in n8n (publicly-reachable endpoints): Every payload is signed with HMAC-SHA256. The X-Warmy-Signature header is Stripe-style `t=<unix_ms>,v1=<hmac_hex>` — you must parse it and verify against the RAW request body (not the parsed JSON).
Two setup steps:
On the Webhook trigger node, under 'Options', enable 'Raw Body' so the raw bytes are preserved on `$binary.data`.
Add a Function node before the Switch with this code:
const crypto = require('crypto'); const secret = $env.WARMY_WEBHOOK_SECRET; // set in n8n credentials/env — never hardcode const headers = $input.first().headers; const sigHeader = headers['x-warmy-signature'] || ''; const parts = Object.fromEntries(sigHeader.split(',').map(p => p.split('='))); const ts = parts.t; const sig = parts.v1; if (!ts || !sig) throw new Error('Missing signature'); if (Math.abs(Date.now() - parseInt(ts, 10)) > 5 * 60 * 1000) throw new Error('Stale timestamp'); const rawBody = Buffer.from($input.first().binary.data.data, 'base64').toString('utf8'); const expected = crypto.createHmac('sha256', secret).update(ts + '.' + rawBody).digest('hex'); const a = Buffer.from(sig, 'hex'); const b = Buffer.from(expected, 'hex'); if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) throw new Error('Bad signature'); // re-parse body for downstream nodes $input.first().json = JSON.parse(rawBody); return $input.all();
If Raw Body isn't enabled, re-serializing $json will NOT byte-match what we signed (key order / whitespace / unicode escaping all differ) and verification will fail 100% of the time.
Note: linkedin.reply_received fires once per enrollment on the FIRST reply. Subsequent messages in the same thread don't re-fire. If you need every inbound message, contact support — this isn't currently exposed as a standalone event.
Advanced: WarmySender API from n8n: Beyond webhook consumption, use n8n HTTP Request nodes to call the WarmySender REST API: • Create prospects: POST /api/v1/prospects (email, firstName, lastName, company, linkedinUrl, custom fields). • Enroll in campaign: POST /api/v1/campaigns/:id/enrollments with prospectIds. • Unenroll: DELETE /api/v1/campaigns/:id/enrollments with emails or prospectIds. • Example: lead replies on WhatsApp via Interakt → n8n workflow unenrolls from WarmySender email campaign to prevent duplicate outreach.
Account Safety (LinkedIn Events): WarmySender's webhook delivery does not make any LinkedIn API calls on your behalf — payloads come from our database state only. Toggling webhooks on or off doesn't change how often we poll LinkedIn via Unipile; your LinkedIn account's daily action limits are driven by campaign sends / invites / profile views, not by webhook activity. Enable as many webhooks as you need.
Reliability:
At-least-once delivery — dedupe on the X-Warmy-Event-Id header on your end.
10 retry attempts with exponential backoff (1 min → 72 h) on non-2xx responses.
5-second timeout per request — set n8n Response Mode to 'Immediately' and process async after.
Best Practices:
Add error-handling nodes (Error Trigger workflow) for CRM API failures.
Store API keys in n8n credentials manager — never hardcode.
Use Idempotency-Key headers on WarmySender create/enroll calls.
For publicly-reachable n8n, always verify X-Warmy-Signature.
Zapier / Make: Same pattern — 'Webhooks by Zapier' (Catch Hook) or Make's Webhook trigger. Copy the URL, paste into WarmySender Settings → Webhooks, chain downstream modules. Zapier/Make handle format translation between our JSON and Slack/HubSpot/etc., but for native Slack, see the 'Slack Notifications' guide — our direct Slack auto-format is simpler than going through Zapier.
Get real-time notifications in Slack when prospects engage with your campaigns — including LinkedIn replies with the message body, email replies, bounces, unsubscribes, and sending-limit alerts. No Zapier, Make, or n8n in the middle: WarmySender auto-detects Slack Incoming Webhook URLs and formats each event as a readable Slack Block Kit card.
What Arrives in Slack:
LinkedIn reply — prospect name, LinkedIn profile URL, full reply body (truncated to ~400 chars), campaign, timestamp
Step 1: Create a Slack Incoming Webhook • Go to api.slack.com/apps → 'Create New App' → 'From scratch'. • Name it 'WarmySender' and pick the workspace where you want alerts. • In the left sidebar under 'Features', open 'Incoming Webhooks' and toggle it On. • Click 'Add New Webhook to Workspace', pick the channel where alerts should land (e.g., #sales-replies), and authorize. • Copy the webhook URL — it looks like https://hooks.slack.com/services/T0.../B0.../xxxx
Step 2: Add the webhook in WarmySender • Settings → Webhooks → New webhook. • Paste the Slack URL. • Select the events you want. Recommended: reply.received, linkedin.reply_received, linkedin.invite_accepted, email.bounced. • Save.
Step 3: Verify • In the webhook row, click the refresh/test button. A test message should appear in your Slack channel within ~10 seconds. • If nothing arrives, check the Slack app's webhook URL is correct and the target channel still exists.
That's it — no middleware, no code, no third-party automation tool.
How It Works: When the webhook URL matches https://hooks.slack.com/…, our delivery worker (server/webhook-deliverer.ts) transforms the JSON payload into Slack Block Kit shape before sending. Other URLs receive the raw signed JSON payload as usual. This means one event can fan out to a Slack channel AND your CRM webhook endpoint simultaneously with zero extra work.
LinkedIn-Specific Events:
linkedin.reply_received — Fires the first time a prospect replies to a LinkedIn message or InMail inside a campaign enrollment. Payload includes the reply body. Follow-up messages in the same thread don't re-fire (matches how campaigns auto-pause on first reply).
linkedin.invite_accepted — Fires once per prospect when they accept your LinkedIn connection request. Detected via Unipile real-time webhooks (message-matched) with polling fallback for accepts without a message — expect up to ~8h detection latency on no-message accepts (Unipile's documented behavior).
Multi-Channel Routing (one event → different channels): Create multiple Slack Incoming Webhooks (one per channel — #sales-replies, #ops-bounces, #linkedin-connected). Add each as a separate webhook in WarmySender with a different event selection. Events fan out in parallel.
Recommended Events Per Channel:
#sales-replies — reply.received, linkedin.reply_received (highest priority; prospect is engaged NOW)
AVOID: email.opened / email.clicked (high volume; floods the channel — use n8n/Zapier with per-campaign filters instead)
Microsoft Teams: Teams uses a different payload format (Adaptive Cards) than Slack. Our native auto-format targets Slack only. For Teams: use the 'n8n Integration' or 'Zapier Integration' guide to translate our JSON to Teams Adaptive Card format in the middle.
Account Safety (LinkedIn Events): Enabling these webhooks does NOT call the LinkedIn API — we emit from database state only, read once on reply detection. Your LinkedIn daily action limits are unaffected.
10 retry attempts with exponential backoff (1 min → 72 h) if Slack is temporarily unreachable.
On Slack 429 Too Many Requests, we honor the Retry-After header automatically.
Privacy Note: Slack messages include prospect email / LinkedIn profile URL / reply body in plain text. Slack retains message history per your workspace's retention policy — choose the destination channel accordingly (private channel for sensitive conversations).
See also: 'Webhooks Getting Started' guide for signing verification, full event catalog, and retry behavior.
Automatically log WarmySender campaign events to Google Sheets for reporting and analysis.
What This Integration Does:
Append a new row to a Google Sheet every time a prospect replies, opens, clicks, bounces, or unsubscribes.
Build custom dashboards and reports from live campaign data.
Share campaign performance with team members who don't have WarmySender access.
Setup via Zapier (Recommended — No Code):
Step 1: Create your Google Sheet • Create a new Google Sheet with column headers: Timestamp | Event Type | Prospect Email | Campaign ID | Step Index | URL Clicked | Details
Step 2: Create a Zap • Trigger: Webhooks by Zapier > Catch Hook. • Copy the Zapier webhook URL.
Step 3: Register in WarmySender • Settings > Webhooks > Create Webhook. • Paste Zapier URL, subscribe to all events you want to log. • Send a test event.
Step 4: Configure the Google Sheets action • Action: Google Sheets > Create Spreadsheet Row. • Select your spreadsheet and worksheet. • Map fields: - Timestamp → data.openedAt / data.clickedAt / data.receivedAt (use Zapier formatter for consistent dates) - Event Type → type - Prospect Email → data.prospectEmail - Campaign ID → data.campaignId - Step Index → data.stepIndex (for opens/clicks) - URL Clicked → data.url (for email.clicked events) - Details → Full JSON payload (optional)
Setup via Make:
Webhook module → Google Sheets 'Add a Row' module.
Use Make's router to format different event types into consistent columns.
Setup via Apps Script (Advanced): Deploy a Google Apps Script web app as your webhook endpoint: 1) Open your Sheet > Extensions > Apps Script. 2) Write a doPost(e) function that parses the webhook JSON and appends a row. 3) Deploy as web app (accessible to 'Anyone'). 4) Use the deployment URL as your WarmySender webhook endpoint.
Reporting Ideas:
Pivot table by campaign to compare reply rates.
Chart daily opens/clicks over time.
Filter by prospect email to see full engagement history.
Use COUNTIF formulas to calculate per-campaign metrics.
Best Practices:
Create separate sheets (tabs) for different event types if volume is high.
Add data validation to prevent sheet corruption.
Set up automatic archiving — move rows older than 30 days to an archive sheet.
Use Google Sheets API quotas wisely — batch operations if volume exceeds 60 events/minute.
Connect WarmySender to GoHighLevel (GHL) for agency CRM sync and lead management.
What This Integration Does:
Create GHL contacts when prospects reply to WarmySender campaigns.
Trigger GHL workflows based on prospect engagement (opens, clicks, replies).
Sync suppression lists between WarmySender and GHL.
Log campaign activity on GHL contact timelines.
Setup via Webhook + GHL API:
Step 1: Get your GHL API credentials • In GHL, go to Settings > Business Profile > API (or use the Agency API for sub-accounts). • Generate an API key or use OAuth for sub-account access.
Step 2: Create a middleware Build a handler that translates WarmySender events to GHL API calls:
reply.received → POST /contacts/upsert (GHL API) with email, name, and source tag. Then POST /contacts/{id}/notes to log the reply.
email.bounced → POST /contacts/upsert, add tag 'bounced', update DND (Do Not Disturb) settings.
email.clicked → POST /contacts/{id}/notes with the clicked URL.
Step 3: Register in WarmySender • Settings > Webhooks > Create Webhook. • Enter your middleware endpoint URL. • Subscribe to: reply.received, email.bounced, email.clicked, email.unsubscribed.
Setup via Zapier (No Code):
Trigger: Webhooks by Zapier (Catch Hook) with WarmySender events.
Zapier has a native GHL integration — no middleware needed.
GHL Workflow Triggers: Once contacts are created in GHL, you can trigger GHL internal workflows: • Contact Created → Assign to pipeline stage. • Tag Added ('replied') → Notify agent, move to appointment booking. • Tag Added ('bounced') → Remove from GHL sequences.
Agency Setup (Multi Sub-Account):
Use GHL Agency API to route contacts to the correct sub-account.
Map WarmySender workspace → GHL sub-account by ID.
Each sub-account can have its own WarmySender webhook endpoint.
Best Practices:
Use GHL's upsert endpoint to avoid duplicate contacts.
Tag contacts with 'warmysender' source for attribution.
Set DND email = true for unsubscribed contacts to prevent GHL from re-emailing them.
Use GHL's custom fields to store WarmySender campaign ID and prospect ID.
Connect WarmySender to Airtable to build a custom engagement tracking database.
What This Integration Does:
Create Airtable records for every campaign event (opens, clicks, replies, bounces).
Build custom views and reports using Airtable's powerful filtering and grouping.
Share live campaign data with team members using Airtable's collaboration features.
Trigger Airtable Automations based on WarmySender events.
Setup via Zapier (Recommended):
Step 1: Prepare your Airtable base • Create a table called 'Campaign Events' with these fields: - Event Type (Single Select: reply.received, email.opened, email.clicked, email.bounced, email.unsubscribed) - Prospect Email (Email) - Campaign ID (Single Line Text) - Step Index (Number) - URL Clicked (URL) - Timestamp (Date) - Raw Payload (Long Text)
Step 2: Create a Zap • Trigger: Webhooks by Zapier > Catch Hook. • Action: Airtable > Create Record. • Map WarmySender event fields to Airtable columns.
Step 3: Register in WarmySender • Settings > Webhooks > paste Zapier URL, subscribe to events.
Setup via Make:
Webhook module → Airtable 'Create a Record' module.
Use Make's router to handle different event types.
Setup via Airtable Automations (Advanced): Airtable has built-in automations with a 'When webhook received' trigger: 1) In your Airtable base, go to Automations > Create Automation. 2) Trigger: 'When webhook received' — Airtable provides a URL. 3) Use that URL as your WarmySender webhook endpoint. 4) Action: 'Create record' in your events table. 5) Map the incoming JSON fields to your table columns.
Useful Airtable Views:
Grid View — Filter by event type or campaign for quick scanning.
Kanban View — Group by event type to see pipeline stages.
Calendar View — See events on a timeline.
Gallery View — Card-style view of prospect activity.
Pivot Table extension — Cross-tab campaign vs. event type.
Best Practices:
Create a linked 'Prospects' table and use Airtable's record linking to connect events to prospect records.
Use Airtable's formula fields to calculate metrics (e.g., reply rate = COUNTIF reply / total events).
Set up Airtable automations to send email or Slack alerts when high-value events occur.
Archive old records monthly to keep your base fast (Airtable slows above 50,000 records).
Connect Claude Desktop, Claude Code, Cursor, Windsurf, Zed, and other MCP-compatible AI clients to your WarmySender workspace using the Model Context Protocol (MCP). Once connected, your AI assistant can list campaigns, enroll prospects, check mailbox health, pause LinkedIn campaigns, update warmup settings, and more — all in natural language, with your account's safety limits enforced by our scheduler.
What Is MCP? MCP (Model Context Protocol) is an open standard from Anthropic that lets AI assistants talk to external tools and data. Instead of copy-pasting information between tabs, you ask your AI — "list my active campaigns," "enroll these 20 prospects in campaign X," "pause the SDR LinkedIn campaign" — and it calls the right WarmySender action on your behalf.
What You Can Do:
List email + LinkedIn campaigns with live counters (sent, opened, replied, bounced)
Enroll / unenroll prospects in bulk (up to 500 per call)
Create, update, and bulk-import prospects (up to 500 per request)
Check mailbox health, warmup stats, and per-mailbox deliverability
List LinkedIn accounts + health + current weekly invite/message usage
Pause / resume LinkedIn campaigns (never direct send — scheduler enforces all account safety)
Enroll prospects in LinkedIn campaigns (queued, scheduler-paced within daily caps)
Update warmup settings per mailbox or in bulk
Add emails or domains to the suppression list
Poll async job status (bulk updates, connection tests)
What You Cannot Do (by design):
No direct LinkedIn sends from MCP — all LinkedIn actions route through the same scheduler the UI uses, which enforces the 4-week ramp, daily/weekly caps, and per-account safety limits. A banned account is unrecoverable, so this is non-negotiable.
No account connect/disconnect — adding or removing a LinkedIn or email account stays in the web UI (prevents a compromised AI from draining your LinkedIn seats).
No delete operations — soft-cancel via pause / archive only; permanent deletes happen in the UI after explicit confirmation.
No modification of warmup subject-line ref tags (protects your inbox filtering).
Supported AI Clients:
Claude Desktop (Mac / Windows)
Claude Code (CLI)
Cursor
Windsurf (Codeium)
Zed
Any client that speaks MCP over Streamable HTTP (the 2025-11 spec)
Authentication: MCP uses your existing WarmySender API key (ws_ prefix). Create one in Settings > API Keys with the scopes you want to expose (e.g., campaigns:read, campaigns:write, prospects:write, linkedin:read, warmup:write). The same key works for both REST API and MCP — no separate credentials.
Scope Mapping (your key needs these for each tool):
pause/resume_linkedin_campaign, enroll_in_linkedin_campaign → linkedin:write (+ campaigns:write for pause/resume)
list_suppressions → suppressions:read
add_to_suppression_list → suppressions:write
get_job_status → jobs:read
Rate Limits (per workspace, per minute):
Read tools: 120 / min
Write tools: 30 / min
LinkedIn writes: 10 / min (stricter — safety)
Bulk operations: 5 / min
These are enforced by Upstash Redis at the MCP layer. Your underlying LinkedIn daily/weekly caps and warmup pacing are enforced separately by the scheduler — MCP cannot bypass them.
Pricing: MCP access is included with any active WarmySender subscription. No separate charge. Your API key usage counts toward the rate limits above.
Next Steps: See the guide "MCP Server — Install in Claude Desktop / Claude Code / Cursor / Windsurf / Zed" for copy-paste install snippets for each client. See "MCP Server — Available Tools Reference" for the full list of 30 tools. See "MCP Server — Safety, Scopes, and Rate Limits" for security and limits deep-dive.
Step-by-step install snippets for every MCP-compatible AI client. The WarmySender MCP server lives at https://warmysender.com/mcp and authenticates with your existing API key (ws_ prefix).
Before You Start — Create an API Key:
Go to Settings > API Keys > Create API Key.
Name it (e.g., "Claude Desktop" so you can revoke per-client later).
Select scopes — match them to what you want the AI to do. For full access pick everything; for read-only monitoring pick only the *:read scopes.
Copy the full key (shown once, starts with ws_). Keep it somewhere safe.
Claude Desktop (Mac / Windows): Claude Desktop natively speaks stdio MCP, not HTTP — so we use the npx mcp-remote bridge to adapt. Open (or create) your claude_desktop_config.json: • Mac: ~/Library/Application Support/Claude/claude_desktop_config.json • Windows: %APPDATA%\Claude\claude_desktop_config.json
Paste this block inside the top-level object (merging with any existing mcpServers):
Replace ws_YOUR_API_KEY_HERE with your real key. Save the file, fully quit Claude Desktop (Cmd+Q, not just close the window), reopen. You should see "warmysender" listed under the MCP section of the tools menu. Try asking: "What LinkedIn campaigns do I have running?"
Claude Code (CLI): Claude Code speaks HTTP MCP natively. Run:
Testing Your Connection: From any client, ask the AI: "Use the get_workspace_info tool to show me my current WarmySender workspace." You should get a JSON response with your workspace name, subscription tier, and the scopes on your API key. If you get an auth error, check that you replaced the placeholder with your real ws_ key. If the tool isn't listed, the client didn't connect — re-check the config file path and restart the client fully.
You should see a Mcp-Session-Id response header and a successful init payload. If curl shows 401, the key is wrong or revoked. If it shows 429, you've hit the rate limit — wait a minute.
Revoking Access: If you lose a device or want to cut an AI client off: Settings > API Keys > find the key you named after that client > Delete. The client's next call will get 401 immediately. You can always create a new key to re-enable.
Troubleshooting:
"Auth failed" — double-check your key starts with ws_, wasn't truncated, and isn't revoked (Settings > API Keys).
"Tool not found" — the client didn't pick up the config; fully quit and reopen.
"Rate limited" (429) — wait ~60s; you hit 120 reads, 30 writes, 10 LinkedIn writes, or 5 bulk ops in a minute.
"Insufficient scope" — the action needs a scope your key doesn't have. Edit the key's scopes in Settings > API Keys (or create a new one) and reconnect.
Claude Desktop still not seeing the server — check that npx is on your PATH (Node.js must be installed). Try running the mcp-remote command manually in Terminal to see errors.
See also: "MCP Server — Available Tools Reference" and "MCP Server — Safety, Scopes, and Rate Limits."
The WarmySender MCP server exposes 30 tools organized into four categories: read-only, email-campaign writes, LinkedIn + warmup writes (safety-gated), and meta. Every tool enforces workspace scoping from your API key — you can only see and touch data in your own workspace.
READ-ONLY (safe to grant freely) — 13 tools:
Campaigns & Prospects:
list_campaigns — List email campaigns, filter by status (draft/running/paused/completed), cursor-paginated. Requires campaigns:read.
get_campaign — Full campaign details including steps and live counters (sent, delivered, opened, clicked, replied, bounced). Requires campaigns:read.
list_prospects — Search and filter prospects by global status, free-text search, cursor-paginated. Requires prospects:read.
get_prospect — Full prospect detail including custom fields, list memberships, and enrollment summary. Requires prospects:read.
Mailboxes & Warmup:
list_mailboxes — All connected mailboxes with status, warmup state, and top-level health. Never returns credentials. Requires mailboxes:read.
get_mailbox_health — Detailed deliverability health for one mailbox: connection errors, auth errors, spam rate, health issues with fix suggestions. Requires mailboxes:read.
get_warmup_stats — Workspace-level aggregate or per-mailbox detail: sent_today, limit_today, ramp progress, inbox rate, health score. Requires warmup:read.
LinkedIn:
list_linkedin_accounts — Connected LinkedIn accounts with strategy, ramp week, and current daily/weekly usage against caps. Requires linkedin:read.
get_linkedin_account_health — Per-account health metrics: acceptance rate, reply rate, restriction count, API budget headroom. Requires linkedin:read.
list_linkedin_campaigns — LinkedIn campaigns by status with top-level counters (enrolled, sent, accepted, replied). Requires linkedin:read.
EMAIL WRITES — 11 tools (all idempotent with optional idempotency_key):
Prospects:
create_prospect — Single prospect with email, name, company, role, phone, linkedinUrl, customFields. Duplicate email returns 409 with existing_id. Requires prospects:write.
update_prospect — Partial update of any field including global_status (active/bounced/unsubscribed/etc.). Requires prospects:write.
bulk_create_prospects — Up to 500 prospects per call with skip_duplicates flag. Returns per-row status. Requires prospects:write. Rate-limit category: bulk (5/min).
update_campaign — Partial update, only allowed on draft or paused campaigns. Requires campaigns:write.
start_campaign — Transition draft → running (or scheduled if startDate is future). Checks: has steps, has mailboxes, subscription active. Requires campaigns:write.
pause_campaign — Running → paused. Marked destructive so clients prompt to confirm. Requires campaigns:write.
resume_campaign — Paused → running with re-scheduling of pending enrollments. Requires campaigns:write.
Enrollments & Suppressions:
enroll_prospects — Add prospects to an email campaign by prospect_ids, list_ids, or emails (pass at least one, max 500 items total). Suppressed prospects auto-skipped. Requires enrollments:write.
pause_linkedin_campaign — Pause a running LinkedIn campaign. No Unipile calls — pure status flip. In-flight sends already queued may complete. Marked destructive. Rate: linkedin_write (10/min).
resume_linkedin_campaign — Paused → running. Pre-flight checks: associated LinkedIn account is connected and healthy; returns 422 account_not_ready if not. Rate: linkedin_write.
enroll_in_linkedin_campaign — Queue prospects (by prospect_ids, audience_id, or linkedin_urls; max 500 total) into a LinkedIn campaign. Only stages work — the scheduler gates actual invites/messages against ramp week and per-account daily/weekly caps. Rate: linkedin_write.
update_warmup_settings — Change warmup enabled/mode/target_daily_volume for one mailbox. Rate: write.
bulk_update_warmup — Apply the same warmup settings to up to 500 mailboxes asynchronously. Returns job_id for polling via get_job_status. Rate: bulk.
META — 1 tool:
get_workspace_info — Returns your workspace id, name, subscription tier, scopes on the current API key, and MCP server version. Useful for testing the connection. No scopes required (authenticated key is enough).
Not Exposed (by design): No delete operations (no delete_campaign, delete_mailbox, delete_account — soft-cancel via pause/archive only). No direct LinkedIn send tools (no sendInvite, sendMessage, viewProfile, commentOnPost, reactToPost — scheduler-only path). No account connect/disconnect tools (seat drain prevention). No warmup ref-tag modification (inbox filtering integrity).
Full schemas and live curl examples: warmysender.com/mcp
How the WarmySender MCP server keeps your account safe when you grant an AI assistant access. Read this before handing a production API key to any AI tool.
CORE SAFETY INVARIANTS:
1) Workspace scoping — every single query Your API key deterministically resolves to exactly one workspace at auth time. Every tool handler filters every database query by that workspace ID. A tool cannot be tricked via arguments into seeing or modifying another workspace's data. The workspace ID never appears in tool input schemas — there's no way for the AI to "pass" a workspace ID.
2) Scheduler-first for all LinkedIn + warmup actions MCP never calls Unipile (LinkedIn API) directly. Tools like pause_linkedin_campaign, resume_linkedin_campaign, enroll_in_linkedin_campaign only flip database state or queue work. Our scheduler — the same one the UI uses — gates actual LinkedIn invites, messages, and profile views against: 4-week ramp schedule, per-account daily cap (invites + messages + profile views), per-account weekly cap (e.g., 200 invites/week for premium, 150 for free with notes), and Unipile's published per-account API budget. A compromised or hallucinating AI client cannot bypass these — the enforcement is in the scheduler, not the tool.
3) No send tools at all No tool in the MCP catalog sends an email, invite, message, InMail, profile view, post comment, or reaction directly. The only way to make WarmySender do outreach is to start a campaign (which the scheduler then paces) or to enroll prospects in an already-running campaign (again, scheduler-paced). This removes an entire class of risk where an AI could be prompted into sending unintended messages.
4) No account connect / disconnect Adding or removing a LinkedIn or email account stays in the web UI behind your logged-in session. A compromised AI assistant cannot drain your LinkedIn seats or provision new accounts on your bill.
5) No delete operations in V1 No delete_campaign, delete_mailbox, delete_prospect, delete_account. Soft-cancel via pause/archive only. Permanent deletes happen in the UI with explicit confirmation.
6) Warmup subject-line ref-tag is untouchable Our warmup emails include a [ref: XXXXXXXX] tag in the subject so you can filter them from your inbox with a simple Gmail / Outlook rule. No MCP tool can remove or modify this tag — protects your inbox hygiene.
SCOPES — PRINCIPLE OF LEAST PRIVILEGE:
Your API key carries a list of scopes. Each tool requires specific scopes. Grant only what you need for the AI to do its job:
These are enforced in Upstash Redis at the MCP edge, independent of LinkedIn / warmup scheduler limits. Exceeding any category returns a 429 with retry_after_seconds.
IDEMPOTENCY: Every write tool supports an optional idempotency_key argument. If the AI retries the same operation (same tool, same args, same key) within 24 hours, you get the original result back — no duplicate effect. Different args with the same key return 409 idempotency_conflict.
AUDIT LOG: Every tool call is logged to our system_logs table with: tool name, workspace ID, API key ID, duration, outcome (ok / error / rate_limited / insufficient_scope), and a sanitized args summary (never full emails, names, phone numbers, or URLs — only hashes, domains, and counts). If something goes wrong, our support team can trace exactly what the AI tried to do.
TRANSPORT SECURITY:
TLS 1.2+ only (HTTPS enforced at the edge).
Bearer token auth — your API key (ws_ prefix, SHA-256 hashed server-side). Never sent as a query parameter, never logged.
Session IDs bound to the API key at initialize time — a confused-deputy attack where a stolen session ID is reused with a different key is rejected.
DATA THE AI NEVER SEES:
SMTP / IMAP passwords, OAuth refresh tokens for your mailboxes.
Stripe / billing details.
Other workspaces' data — ever.
User login credentials / session cookies.
RED-TEAM TESTS WE RAN:
Try to access another workspace by passing a forged ID in tool args — blocked (args never carry workspace ID).
Try to exceed rate limits by opening multiple MCP sessions with the same key — blocked (limits are per-workspace, not per-session).
Try to call write tools with a read-only key — blocked (-32001 insufficient_scope, message lists exactly which scope is missing).
Try to retrieve mailbox credentials via list_mailboxes — blocked (response shape explicitly omits credential fields).
Try to bypass LinkedIn daily caps by spamming enroll_in_linkedin_campaign — the scheduler still paces actual invites regardless of enrollment queue depth.
DISABLING MCP COMPLETELY: MCP has no global kill switch — the controls are per-key: Settings > API Keys > Delete every key. With zero API keys, no MCP client can authenticate. You can always re-enable by creating new keys.
QUESTIONS? If you need a scope combination not listed, or a tool that isn't in our catalog, contact hello@warmysender.com — we extend the server carefully (safety first), but legitimate requests are welcome.
See also: "MCP Server — Overview" and "MCP Server — Install in Claude Desktop / Claude Code / Cursor / Windsurf / Zed" and "MCP Server — Available Tools Reference."
This error usually means you're using your regular Google password instead of an App Password. Google requires App Passwords for third-party applications when 2-Step Verification is enabled. Go to myaccount.google.com/apppasswords, generate a new App Password, and use that 16-character password in WarmySender instead of your regular password.
This error indicates the wrong SMTP or IMAP host or port is being used. Double-check the server settings for your email provider in the Provider Setup Guides above. Common mistakes include using port 587 with SSL (should be STARTTLS) or port 465 with STARTTLS (should be SSL). Make sure there are no typos in the hostname.
This error means your email provider's administrator has disabled SMTP authentication at the organization level. This is common with Microsoft 365 accounts and is NOT a password issue — regenerating your App Password will not fix it.
Error codes you may see:
5.7.139 — SMTP client authentication disabled for the tenant/organization
5.7.57 — Client not authenticated, SMTP AUTH disabled
5.7.3 — Authentication unsuccessful, SMTP AUTH blocked by policy
'Basic authentication is disabled' — Security Defaults are enabled in your org
How to fix (requires your IT admin):
For Microsoft 365:
Your admin must go to Microsoft 365 Admin Center (admin.microsoft.com).
Navigate to Users → Active Users → Select your account.
Click the Mail tab → Manage email apps.
Check the box for 'Authenticated SMTP' and save.
Wait 15-30 minutes for the change to propagate.
If your organization has Security Defaults enabled (common for new M365 tenants):
Your admin must go to Azure Portal (portal.azure.com) → Microsoft Entra ID → Properties.
Click 'Manage Security Defaults' at the bottom.
Set 'Security defaults' to Disabled (note: this reduces security for the entire org — discuss with your IT team).
Alternatively, create a Conditional Access policy that exempts SMTP AUTH from MFA requirements (more secure than disabling Security Defaults entirely).
For Google Workspace: This error is rare with Google, but if you see it: 1) Your admin must go to admin.google.com → Apps → Google Workspace → Gmail → End User IMAP/POP Access. 2) Ensure IMAP access is enabled for your organizational unit. 3) Check that 'Allow users to manage their App Passwords' is enabled under Security → Authentication.
Note: This is a server-side policy change that only your IT administrator can make. WarmySender cannot bypass organization-level security policies. Send your admin the steps above or forward them this guide.
This error means the SMTP or IMAP hostname you entered does not exist or cannot be resolved by DNS. The mail server address is incorrect.
Common causes:
Typo in the hostname — Double-check for misspellings (e.g., 'smpt.gmail.com' instead of 'smtp.gmail.com').
Using your domain instead of the provider's hostname — For example, entering 'mail.yourdomain.com' when you should use 'smtp.gmail.com' (Gmail) or 'smtp.office365.com' (Outlook).
Domain expired or DNS not configured — If using a custom domain, verify it has not expired and has valid MX records.
Temporary DNS issue — Try again in a few minutes. If persistent, try using a different network or contact your internet provider.
This error means the mail server rejected your username or password. You may see SMTP error codes such as 535 5.7.8 (Authentication credentials invalid), 535 5.7.3 (Authentication unsuccessful), 534 5.7.9 (Application-specific password required), or 534 5.7.14 (Please log in via your web browser first).
Common causes:
Using your regular account password instead of an App Password.
An expired or revoked App Password.
A typo in your email address or password.
SMTP authentication not enabled on your account.
Two-Factor Authentication (2FA) enabled without generating an App Password.
Provider-Specific Steps:
Gmail:
You must use an App Password, not your regular Google password.
Go to https://myaccount.google.com/apppasswords (2FA must be enabled first).
Generate a new App Password for 'Mail' and paste it into WarmySender.
Your username must be your full Gmail address (e.g., you@gmail.com).
Outlook / Microsoft 365:
Generate an App Password at https://account.live.com/proofs/AppPassword or via your M365 admin portal.
Ensure SMTP AUTH is enabled: In Microsoft 365 Admin Center, go to Users > Active Users > select the user > Mail tab > Manage email apps, and check 'Authenticated SMTP'.
Your username must be your full email address (e.g., you@outlook.com or you@yourdomain.com).
If you see error 534 5.7.14 or 'Please log in via your web browser', sign in to Outlook on the web first and complete any security prompts.
Hostinger:
Use your regular email password (not an App Password).
SMTP host must be smtp.hostinger.com (not mail.yourdomain.com).
Your username is your full email address (e.g., you@yourdomain.com).
If you recently changed your password, wait a few minutes for propagation.
Zoho:
If 2FA is enabled, generate an App Password at https://accounts.zoho.com/home#security/security_apppassword.
If 2FA is not enabled, your regular Zoho password should work.
Your username is your full email address.
SMTP host: smtp.zoho.com (or smtp.zoho.eu / smtp.zoho.in depending on your region).
Yahoo:
You must use an App Password. Go to https://login.yahoo.com/account/security and generate one under 'App Passwords'.
Your username is your full Yahoo email address.
Debugging Steps:
Verify your username is your full email address (e.g., user@domain.com), not just the part before the @.
Re-generate a fresh App Password and paste it carefully — avoid trailing spaces.
Confirm the SMTP host and port match your provider's requirements (see Provider Setup Guides).
Log in to your email provider's web interface and check for any security alerts or prompts that need to be resolved.
If you recently enabled 2FA, any previously saved passwords are invalidated — generate a new App Password.
Try disabling and re-enabling SMTP access in your provider's settings.
Still Not Working? • Check your provider's status page for outages. • Try connecting from a different network (some corporate networks interfere with SMTP authentication). • Contact your email provider's support team and confirm that SMTP access with third-party apps is allowed on your account. • As a last resort, try a different email provider to isolate whether the issue is account-specific.
SSL/TLS certificate errors are among the most common connection issues. Here is a comprehensive guide to diagnosing and fixing them:
Error: 'Self-signed certificate' or 'DEPTH_ZERO_SELF_SIGNED_CERT' This means your mail server uses a certificate that is not issued by a trusted Certificate Authority (CA). Common with self-hosted mail servers, Plesk, cPanel, or shared hosting.
Solutions (try in order):
Check port and security match — This is the #1 cause. Port 465 requires SSL. Port 587 requires STARTTLS. They are NOT interchangeable. Using the wrong combination produces certificate errors.
Use your provider's official SMTP/IMAP hostnames — Do not use your domain name (e.g., mail.yourdomain.com) if your provider has official hostnames. For example, Hostinger users should use smtp.hostinger.com, not mail.yourdomain.com.
Check with your hosting provider — If you use shared hosting (Hostinger, Bluehost, GoDaddy, Namecheap, SiteGround), your mail server's SSL certificate may be on a different hostname. Ask your host for the correct SMTP and IMAP hostnames that match their SSL certificate.
Verify the certificate is not expired — Expired certificates cause 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' errors. Contact your hosting provider to renew the SSL certificate on your mail server.
If self-hosted (VPS, dedicated server) — Install a valid SSL certificate from Let's Encrypt (free) or another CA on your mail server. Most mail servers (Postfix, Dovecot, hMailServer) support Let's Encrypt certificates.
Check for hostname mismatch — The SSL certificate's Common Name (CN) or Subject Alternative Names (SAN) must match the hostname you are connecting to. If your certificate is for 'mail.hostingprovider.com' but you are connecting to 'mail.yourdomain.com', you will get ERR_TLS_CERT_ALTNAME_INVALID.
Use the hosting provider's shared hostname — Many shared hosts have a hostname like 'server123.hostingprovider.com' that matches their SSL certificate. Use that instead of your custom domain.
Ask your provider to add your domain to the certificate — Some providers can add your domain as a SAN entry to their mail server's SSL certificate.
Error: 'STARTTLS not supported' The server does not support STARTTLS on the port you chose. Switch to port 465 with SSL, or confirm your provider supports STARTTLS on port 587.
Error: 'Wrong version number' or 'SSL routines' You are using SSL on a STARTTLS port or vice versa. Port 587 = STARTTLS. Port 465 = SSL. Switch accordingly.
Still Not Working? • Try connecting from a different network (some corporate firewalls block SMTP ports). • Temporarily try port 25 if available (unencrypted, not recommended for production). • Contact your email hosting provider's support team and ask them for the exact SMTP host, port, and security settings that work with third-party applications. • As a last resort, consider migrating to a provider with proper SSL support (Gmail, Outlook, Zoho, Fastmail all have valid certificates).
Note: WarmySender requires a valid SSL certificate for secure email delivery. Self-signed certificates are accepted for connection but may cause intermittent issues. We strongly recommend using a properly signed certificate.
This error means the mail server could not find an account matching the username you provided. The server is reachable and accepting connections, but the specific mailbox does not exist or is not recognized.
Common Causes:
Wrong username format — Your username must be your full email address (e.g., john@yourdomain.com), not just 'john' or a partial address. This is the most common cause.
Typo in email address — Double-check for misspellings, extra spaces, or wrong domain (e.g., @gmial.com instead of @gmail.com).
Email account disabled or deleted — The account may have been suspended, deactivated, or deleted by your email provider or domain administrator. Log in to your provider's web interface to verify the account is active.
Alias vs. primary address — Some providers only accept the primary email address for SMTP login, not aliases or distribution group addresses. Try using your primary mailbox address instead.
Provider-Specific Notes:
Gmail — Your username is always your full Gmail or Google Workspace address.
Outlook/M365 — Use your primary email address, not a shared mailbox or alias. Shared mailboxes require special configuration by your M365 admin.
Hostinger — Use the full email address you created in Hostinger's email panel (e.g., info@yourdomain.com).
Zoho — Use the primary address from your Zoho Mail account. Make sure you are using the correct regional domain (zoho.com, zoho.eu, zoho.in).
Custom/self-hosted — Verify the account exists in your mail server's admin panel (Plesk, cPanel, etc.).
Debugging Steps:
Copy-paste your email address to avoid typos.
Log in to your email provider's webmail to confirm the account is active and accessible.
Check with your domain administrator that the mailbox has not been deleted or disabled.
If using a custom domain, verify that MX records are properly configured and pointing to the correct mail server.
It is normal for some warmup emails to land in spam during the first few days, especially for new mailboxes or domains. WarmySender's spam rescue feature automatically detects and moves these emails to your inbox, which trains email providers to trust your address. Give it 1-2 weeks for your reputation to improve. If spam placement persists after 2 weeks, check that your SPF, DKIM, and DMARC records are correctly configured.
If your warmup is enabled but you see very few or no emails being sent, check these common causes:
Mailbox Connection — Go to your mailbox and verify the status shows 'Connected'. If it shows an error or 'Disconnected', reconnect the mailbox.
Warmup Toggle — Make sure warmup is actually enabled for the mailbox (the toggle should be on).
Early Ramp Phase — If your mailbox just started warmup, the system begins with only 1-3 emails per day and gradually increases over time. This is normal and by design. Check your ramp speed setting.
Subscription Status — Warmup requires an active paid subscription. If your subscription expired or was cancelled, warmup is automatically paused.
Daily Limit Already Reached — If you are running campaigns alongside warmup, the combined volume may have reached your daily plan limit. Check your daily usage in the mailbox details.
Recovery Mode — If the system detected reputation issues, it may have auto-switched your mailbox to Recovery mode, which intentionally reduces volume. Check your warmup strategy in the mailbox settings.
Health Score Below Threshold — If your health score is very low (critical range), the system may temporarily reduce sending to protect your domain.
If none of these apply, try disconnecting and reconnecting your mailbox, then re-enabling warmup.
If your campaign is not sending emails, check the following: 1) Verify your mailbox is connected and showing a green status. 2) Check that your warmup health score is above 70 (campaigns may pause if deliverability is low). 3) Confirm your daily sending limit hasn't been reached for today. 4) Make sure your campaign status is 'Active' and not paused. 5) Check your sending schedule to ensure the current time falls within your sending window and on an active sending day.
If you see rate limiting errors, it means too many actions are being attempted in a short period. WarmySender enforces safety limits to protect your accounts: email campaigns respect per-mailbox daily limits, and LinkedIn actions are limited to 2 per minute per account. Solutions: 1) Reduce your daily sending volume. 2) Spread sending across more mailboxes using mailbox rotation. 3) For LinkedIn, reduce the number of concurrent campaigns per account. 4) Wait a few minutes and the system will automatically resume sending. Rate limits reset daily.
If your mailbox shows a red 'Disconnected' status: 1) Your password or App Password may have expired or been revoked — regenerate it from your email provider and update it in WarmySender. 2) For Gmail: if you recently changed your Google password, all App Passwords are revoked and need to be recreated. 3) For Outlook: App Passwords expire if not used for 90 days. 4) Check that 2-Factor Authentication is still enabled (required for App Passwords). 5) Your email provider may have blocked the connection due to suspicious activity — log into your email directly and check for any security alerts. 6) Go to Mailboxes, click the disconnected mailbox, and re-enter your credentials. The system will test the connection automatically.
When your daily or monthly sending limit is reached, campaigns pause automatically until the limit resets. Daily limits by plan: Pro ($14.99/mo) = 333 emails/day (10,000/month), Business ($29.99/mo) = 3,333 emails/day (100,000/month), Enterprise ($69.99/mo) = 10,000 emails/day (300,000/month). Per-mailbox combined limits (warmup + campaigns) also apply. Solutions: 1) Wait until tomorrow when daily limits reset. 2) Upgrade your plan for higher quotas. 3) Add more mailboxes and use mailbox rotation to spread volume. 4) Reduce warmup volume to free up quota for campaigns. Check your current usage in the Billing page.
If your LinkedIn account is restricted: 1) LinkedIn may have detected automated activity — the restriction is temporary (usually 24-72 hours). 2) Do NOT attempt any actions while restricted — let the cooldown expire. 3) WarmySender's circuit breaker automatically detects restrictions and pauses your LinkedIn campaigns. 4) After the restriction lifts, the system will automatically resume with reduced limits and ramp back up gradually over 4 weeks. To prevent future restrictions: keep daily connection requests under 20, personalize every invite note, avoid sending on weekends, and let the warmup ramp-up complete fully before increasing volume. If your account is permanently restricted by LinkedIn, you will need to appeal directly through LinkedIn's help center.
Low invite acceptance rates are common — typical acceptance rates range from 20-40%. To improve: 1) Always include a personalized note (up to 300 characters) — generic invites get ignored. 2) Mention something specific about the person's profile, company, or a shared connection. 3) Keep your own LinkedIn profile professional and complete. 4) Target relevant prospects — people in your industry accept more often. 5) If a prospect hasn't accepted within your campaign's 'Wait Accept' timeout, the campaign will move to the conditional branch (if configured) or stop for that prospect. 6) Use 'View Profile' as a first step before sending an invite — this creates a notification and increases acceptance rates.
Campaigns auto-enter cooldown when safety thresholds are exceeded. This protects your sender reputation. Triggers: 1) Bounce rate exceeds 5% (default threshold). 2) Spam complaints reach the configured limit (default: 3 complaints). Cooldown lasts 24 hours minimum. After 24 hours, the system checks if metrics have improved — if yes, the campaign resumes automatically; if not, cooldown is extended. To fix: 1) Check your prospect list quality — remove invalid or catch-all email addresses. 2) Verify your DNS records (SPF, DKIM, DMARC) are correct. 3) Lower your daily sending volume. 4) If bounce rate was the trigger, enable Bounce Shield in Settings to pre-validate emails. The campaign status will show 'Cooldown' in orange on your Campaigns page.
Common CSV import issues: 1) File must be UTF-8 encoded CSV with headers in the first row. 2) Maximum 10,000 rows per import — split larger files. 3) Required column: 'email' — rows without a valid email are skipped (unless they have a linkedinUrl, which creates a LinkedIn-only prospect). 4) Check column mapping — after upload, you map CSV columns to WarmySender fields (email, firstName, lastName, company, role, phone, linkedinUrl, website, country, city, industry). 5) Duplicates are automatically skipped — if an email already exists in your workspace, it won't be imported again. 6) Suppressed emails are skipped — check your blocklist in Settings. 7) Invalid emails (failing MX validation) are skipped. 8) For custom fields, prefix your CSV column headers with 'custom:' (e.g., 'custom:department'). Check the import job status for a breakdown of created, skipped, duplicate, and invalid counts.
Custom tracking domains require a CNAME DNS record pointing to track.warmysender.com. Common issues: 1) 'No CNAME record found' — You haven't added the DNS record yet, or it hasn't propagated. Add a CNAME record for your chosen subdomain (e.g., track.yourdomain.com) pointing to track.warmysender.com. 2) 'CNAME record points to wrong target' — Your CNAME points somewhere else. Update it to point to track.warmysender.com exactly. 3) DNS propagation can take up to 48 hours — try verifying again later. 4) Some DNS providers require you to enter the subdomain only (e.g., 'track') without the full domain. 5) Make sure you don't have conflicting A records on the same subdomain. After verification succeeds, select the tracking domain in your campaign settings to use it for open and click tracking.
If your campaign emails land in Promotions or spam: 1) Check DNS records — SPF, DKIM, and DMARC must all be configured correctly. Use a tool like MXToolbox to verify. 2) Reduce HTML and images — plain-text-style emails with minimal formatting have higher inbox placement. 3) Avoid spam trigger words — 'free', 'guarantee', 'act now', 'limited time' in subject lines. 4) Warm up your mailbox first — run warmup for at least 2-3 weeks before starting campaigns. 5) Keep your volume low initially (20-30 emails/day) and increase gradually. 6) Personalize every email — use merge tags so each email is unique. 7) Set up a custom tracking domain to avoid shared tracking domain reputation issues. 8) Monitor your warmup Health Score — if it drops below 60, pause campaigns and let warmup recover your reputation. 9) Use Bounce Shield to filter out invalid emails before sending.
WarmySender automatically adds a visible unsubscribe link to every campaign email — no setup needed. You do not need to add anything manually in the campaign editor.
What happens automatically:
A visible 'Unsubscribe from this list' footer link is appended to every campaign email
RFC 2369/8058 List-Unsubscribe headers are added for one-click unsubscribe in Gmail and Outlook
No configuration required — this is always on for deliverability and compliance
When a prospect clicks unsubscribe:
They are immediately removed from all active campaigns in your workspace
Their status is set to 'unsubscribed' globally
They are added to your suppression list automatically
They will not receive any future campaign emails from your workspace
Campaigns with 'Stop on Unsubscribe' enabled (default: ON) immediately stop the sequence
Viewing unsubscribed contacts:
Go to your prospect list and filter by 'Unsubscribed' status
Unsubscribed prospects remain in your database but are excluded from all sending
Compliance:
This is required for CAN-SPAM and GDPR compliance
Never manually re-add unsubscribed contacts to campaigns
The unsubscribe link uses signed tokens (HMAC-SHA256) for security — links cannot be forged
If you connected via OAuth (Google Sign-In or Microsoft Sign-In) and the connection stops working: 1) OAuth tokens expire periodically and need to be refreshed. 2) If automatic refresh fails, you'll need to reconnect. Go to Mailboxes, click the affected mailbox, and re-authenticate. 3) For Google: tokens may be revoked if you changed your Google password, removed app access in Google Security settings, or if the token hasn't been used in 6 months. 4) For Outlook: tokens expire if your Microsoft admin changed security policies, or if you changed your password. 5) Check your email provider's third-party app access settings to make sure WarmySender is still authorized. After re-authenticating, warmup and campaigns will resume automatically.
If your WarmySender campaign analytics show fewer accepted connections than what you see on LinkedIn, this is normal behavior. There are several reasons for the discrepancy:
Tracking window — WarmySender only tracks connection acceptances that happen while the campaign is active and monitoring. If a prospect accepts your invite after the campaign completes or after the 'Wait Accept' timeout expires, that acceptance is not counted in campaign analytics.
Manual acceptances — If you sent connection requests outside of WarmySender (directly on LinkedIn), those are not tracked in campaign analytics.
Wait Accept timeout — Each 'Wait Accept' step has a maximum wait time (default: 14 days). If a prospect accepts after this timeout, the campaign has already moved them to the timeout branch and the acceptance is not retroactively counted.
Sync timing — LinkedIn connection acceptance data is synced periodically. There may be a short delay between when someone accepts and when it appears in your analytics.
Account-level vs. campaign-level — Your LinkedIn account may show total connections from all sources (manual, other campaigns, organic). WarmySender analytics only show connections from that specific campaign.
If your campaign appears paused or is not sending emails even though it is within the active sending window, check these common causes:
Subscription status — If your subscription expired, was cancelled, or payment failed, all campaigns are auto-paused. Check Billing page for your subscription status. Campaigns auto-resume when you re-subscribe.
Campaign status — Make sure the campaign status is 'Running' (not 'Draft', 'Paused', 'Cooldown', or 'Completed'). Check the Campaigns page for the status badge.
No available mailboxes — All assigned mailboxes may be disconnected, in error state, or have hit their daily limits. Check Mailboxes page for connection status. At least one mailbox must be active and connected.
Daily limit reached — Your plan's daily sending limit or per-mailbox daily limit may be exhausted. Check your Billing page for usage. Limits reset at midnight.
Bounce rate exceeded — If your campaign's bounce rate exceeded 5% (default threshold) with at least 50 sends, it enters 'Cooldown' mode automatically. Check campaign analytics for bounce rate.
Sending window mismatch — Verify the campaign's sending window (start/end hours) and timezone match when you expect sends. A campaign set to 9 AM-5 PM Eastern won't send during those hours Pacific.
Schedule days — Check that today is an active sending day. If the campaign is set to Mon-Fri only, it won't send on weekends.
No eligible prospects — All enrolled prospects may have already been contacted, replied, bounced, or unsubscribed. Check the campaign's prospect enrollment status.
Campaign end date passed — If you set an end date and it has passed, the campaign stops automatically.
Rate limiting backoff — After hitting a rate limit, the system backs off before retrying. This can cause temporary pauses of 1-60 minutes.
How to Diagnose:
Check campaign detail page for the 'Paused Reason' field (if paused).
Check campaign analytics for recent send activity.
Check your mailbox connection status in the Mailboxes page.
Check Billing for subscription and usage status.
If none of these apply and your campaign is still not sending, contact support at hello@warmysender.com with your campaign name and account email.
LinkedIn connection request steps in campaigns allow blank invite notes — it is not required to include a personalized message. If you are unable to save a step, the issue is likely one of the following:
Character limit exceeded — Invite notes are limited to 300 characters. If your message exceeds this limit, the save will fail. Check the character counter in the step editor.
Step type mismatch — Make sure the step type is set to 'Send Invite' (not 'Send Message' or 'Send InMail'). Message and InMail steps may have different validation rules.
Template selection issue — If you selected a template but then cleared the text, try deselecting the template entirely (set template to 'None') before saving.
Browser cache — Try refreshing the page (Ctrl+F5 / Cmd+Shift+R) and re-entering the step configuration.
Network error — Check your internet connection. The save may have failed due to a network timeout rather than a validation error.
Note on Blank Invites:
Blank invites are allowed but not recommended — the editor shows a warning: 'Personalized notes increase acceptance rates by 40%+'
This is a warning only, not a blocking error.
If you intentionally want to send blank connection requests, simply leave the invite note field empty and save the step.
Some users prefer blank invites because LinkedIn's own connection suggestions do not include notes, making blank requests appear more organic.
The 'p=none' setting is monitor-only (recommended for start).
Common mistake: Missing the underscore in _dmarc.
5) Verification in WarmySender:
Go to Analytics > Mailboxes to see SPF/DKIM/DMARC status per domain.
Green checkmark = configured correctly.
Red X = missing or misconfigured — hover for details.
6) Still failing? • Flush DNS cache: nslookup -type=txt yourdomain.com 8.8.8.8 • Check your DNS provider did not add extra quotes around TXT values. • Verify you are editing the correct domain (not a subdomain). • Contact your DNS provider support if records appear correct but still fail verification.
If your warmup volume seems stuck or is ramping up too slowly:
Normal behavior — New domains start at 1-3 emails/day with Conservative ramp. This is intentional to protect your domain. The system increases volume gradually over 2-4 weeks.
2) Check your ramp speed — Go to Warmup, click your mailbox, and check the ramp speed setting: • Conservative: 0.08 growth rate (slowest, safest for new domains) • Normal: 0.12 growth rate • Aggressive: 0.20 growth rate (only for established domains) If you are on Conservative and your domain has some history, consider switching to Normal.
Check your daily volume cap — Your configured max daily warmup emails may be limiting volume. The system ramps toward this target but won't exceed it.
Recovery mode — If your mailbox auto-switched to Recovery mode due to high bounce or spam rates, volume is intentionally reduced. Check your warmup strategy in mailbox settings. Let Recovery complete before expecting higher volume.
Shared quota — If you are running campaigns, warmup and campaigns share the daily sending limit. Campaign sends reduce available warmup capacity.
Peer availability — During off-peak hours or with a small warmup pool, fewer peers may be available. This is temporary and self-correcting.
Connection issues — Verify your mailbox shows 'Connected' status. A disconnected mailbox cannot send or receive warmup emails.
Plan limits — Check that your subscription is active. Free or expired plans may have reduced warmup capacity.
If volume has been stuck at the same level for more than 7 days with no obvious cause, disconnect and reconnect your mailbox, then re-enable warmup.
If recipients are marking your campaign emails as spam, take immediate action:
Impact — Spam complaints are the most damaging signal to your sender reputation. Even 1-2 complaints per 1,000 emails can significantly lower your domain reputation with Gmail and Outlook.
Automatic protection — WarmySender tracks spam complaints. If complaints exceed your campaign's threshold (default: 3), the campaign enters Cooldown mode and stops sending.
3) Immediate steps:
Pause the campaign manually if it has not auto-paused.
Review your email content — is it clearly irrelevant or overly aggressive?
Check your prospect list quality — are you sending to the right audience?
Verify your unsubscribe link is visible and working.
4) Root causes and fixes:
Wrong audience — Sending B2B emails to B2C contacts, or irrelevant industry targeting. Fix: Clean your list and improve targeting.
Aggressive content — Hard-sell language, excessive frequency, or misleading subject lines. Fix: Soften your approach and add more value.
No relationship — Cold emailing people who have zero context about you. Fix: Add a warm touchpoint first (LinkedIn view/connect, referral mention).
Missing unsubscribe — Although WarmySender adds unsubscribe links automatically, check that your email template does not accidentally hide or override them.
Old data — Emailing contacts from outdated lists (people who changed jobs). Fix: Re-verify lists and remove stale contacts.
5) Recovery:
Let the campaign Cooldown complete (24+ hours).
Clean your prospect list — remove contacts in industries or roles with high complaint rates.
Reduce daily volume to 10-15 emails/day.
Run warmup in Recovery mode for 2-3 weeks.
Monitor Health Score — resume campaigns only when it recovers above 70.
Session expired — Sessions last 30 days by default. After expiry, you need to log in again. This is normal security behavior.
Forgot password — Use the 'Forgot Password' link on the login page to receive a password reset email. Check your spam folder if you don't receive it within 5 minutes.
3) Browser issues:
Clear your browser cookies and cache for warmysender.com.
Try an incognito/private window.
Disable browser extensions that may block cookies (ad blockers, privacy extensions).
Ensure cookies are enabled for warmysender.com.
Multiple workspaces — If you belong to multiple workspaces, you are logged into one at a time. Use the workspace switcher in the sidebar to switch between them.
Account disabled — If your subscription expired or was deactivated, you can still log in but access is limited to the Billing page for reactivation.
Rate limiting — After multiple failed login attempts, your IP may be temporarily rate-limited. Wait 15 minutes before trying again.
7) Team member access — If you were invited to a workspace and cannot access it:
Check that you accepted the invitation email (click the link in the invite).
Verify you are logging in with the same email address the invitation was sent to.
Ask the workspace owner to check your invitation status in Settings > Team.
If none of these resolve your issue, contact support at hello@warmysender.com with your account email for assistance.
If your webhook endpoint is not receiving events from WarmySender:
Check webhook status — Go to Settings > Webhooks and verify your webhook is active (not paused). Check the delivery history for any failed deliveries.
2) Verify endpoint URL — Make sure your webhook URL is:
Publicly accessible (not localhost or behind a firewall)
Using HTTPS (HTTP may be blocked)
Returning a 200 status code within 5 seconds
Test your endpoint — Click 'Test' in webhook settings to send a test event. If the test fails, your endpoint has an issue.
Event selection — Verify you have subscribed to the correct events. Available events: reply.received, email.bounced, email.unsubscribed, email.opened, email.clicked, prospect.suppressed, limit.hit. For example, reply.received only fires when a reply is detected in a campaign.
5) Check delivery history — Each webhook shows recent delivery attempts with status codes. Common errors:
404 — Your endpoint URL is wrong or the route does not exist.
500 — Your endpoint is throwing an error. Check your server logs.
Timeout — Your endpoint took more than 5 seconds to respond. Return 200 immediately and process asynchronously.
Connection refused — Your server is down or not accepting connections.
Retry policy — Failed deliveries are retried up to 10 times with exponential backoff (1min to 72hrs). Events are not lost on first failure.
Signature verification — Verify using the X-Warmy-Signature header with your webhook secret (HMAC-SHA256). Format: t=timestamp,v1=signature.
Firewall/network — Ensure your server's firewall allows incoming POST requests from WarmySender's servers.
For testing without a live endpoint, use services like webhook.site or requestbin.com to create a temporary endpoint and verify events are being sent.
If you encounter errors when searching LinkedIn or notice some filters aren't working:
Industry filter not available? The industry filter requires a Sales Navigator or Recruiter LinkedIn account. Basic and Premium LinkedIn accounts can search by keywords, location, job title, and company, but cannot filter by industry. If you need industry filtering, consider upgrading to LinkedIn Sales Navigator.
Getting 'Invalid search request' errors? • Make sure you've selected at least one filter (keywords, location, etc.) • For basic LinkedIn accounts, try adding keywords along with your location filter for better results • If the error persists, try reconnecting your LinkedIn account
Getting 'Account connection expired' errors? Your LinkedIn session may have expired. Go to LinkedIn Accounts and reconnect your account.
Search returning unexpected results? • Basic accounts have more limited search capabilities than Sales Navigator • Job title and company fields are combined into the keyword search on basic accounts • For precise filtering, consider using a Sales Navigator account
LinkedIn enrichment is intentionally rate-limited to protect your LinkedIn account from restrictions or bans. Here is why it takes time and what you can do:
Why Enrichment Is Slow: Each enrichment request fetches a full LinkedIn profile through your connected account — the same way you would manually view a profile on LinkedIn. LinkedIn monitors how many profiles you view per day and will restrict accounts that view too many. To prevent this, WarmySender enforces a daily cap based on your account strategy:
New Account (week 1): ~10 profiles/day
Established (week 1): ~30 profiles/day
Veteran (week 1): ~50 profiles/day
Recovery: ~5 profiles/day
For a new account with 1,000 profiles, the math is: 1,000 / 10 = ~100 days at week 1 rates. However, the cap increases each week as your account ramps up — so actual time is shorter as your account matures.
Can I Speed It Up? The enrichment rate cannot be manually increased — it is governed by your account's safety strategy. However: 1) Your daily cap increases automatically each week. By week 4-6, you may be enriching 40-80 profiles/day. 2) If your account was incorrectly classified as 'new' but is actually older, check LinkedIn > Accounts and verify your account age setting. 3) Veteran accounts (1+ year) get the fastest enrichment rates.
Do I Need to Wait? No — you can start a LinkedIn campaign immediately without waiting for enrichment. Enrichment adds extra personalization data but is not required. See the 'LinkedIn Campaigns' guide for details.
When the Daily Cap Resets: The daily cap resets at midnight UTC. Enrichment pauses when the cap is reached and resumes automatically the next day.
Tip: For large audiences (500+ profiles), consider starting your campaign immediately and letting enrichment run in parallel. Personalization data will become available as profiles are enriched.
If your LinkedIn enrichment job shows 'Failed' status or stopped processing, here are the common causes and solutions:
1) Account Disconnected During Enrichment: The most common cause. If your LinkedIn account loses connection while enrichment is running, the job fails with 'Account disconnected during enrichment'. Solution: Go to LinkedIn > Accounts, reconnect your account, then go to LinkedIn > Audiences, select your audience, and click 'Restart Enrichment'.
2) Circuit Breaker Triggered: If 10 or more enrichment errors occur in a single day, the circuit breaker stops enrichment to protect your account. This can happen if LinkedIn is temporarily rate-limiting your profile views. Solution: Wait 24 hours for the circuit breaker to reset, then restart enrichment from the Audiences page.
3) Audience Was Deleted: If you deleted and recreated an audience while enrichment was running on the old one, the job fails with 'Audience was deleted'. This is expected — simply start enrichment on the new audience.
4) Daily Cap Reached (Not a Failure): If enrichment shows 'Paused' (not 'Failed'), it has reached the daily cap and will resume automatically at midnight UTC. This is normal behavior — no action needed.
5) Multiple Failed Connection Attempts: If your LinkedIn account keeps disconnecting, there may be an issue with your LinkedIn session or proxy. Try: a) Reconnect with fresh credentials, b) Check your proxy settings in LinkedIn > Accounts, c) Verify your LinkedIn account is not restricted by LinkedIn itself.
After Fixing the Issue:
Reconnect your LinkedIn account if disconnected
Go to LinkedIn > Audiences and select your audience
Click 'Start Enrichment' or 'Retry' to restart the process
Previously enriched profiles are cached — the system picks up where it left off, not from scratch
A common question is why WarmySender uses your own LinkedIn account for enrichment instead of a separate 'WarmySender' account. Here is the technical explanation:
LinkedIn Has No Public Profile API: Unlike some social platforms, LinkedIn does not offer a public API for viewing profile data. Every profile view requires an authenticated LinkedIn session — meaning a real, logged-in LinkedIn account must be used.
Why Not a Shared System Account? • LinkedIn actively detects accounts that view hundreds or thousands of profiles per day from a single source. A shared 'system' account would be banned within hours. • A banned system account would instantly affect ALL users — not just one. • LinkedIn monitors IP addresses, user agents, and viewing patterns. A single account viewing profiles across many different industries and geographies is a clear bot signal. • Your own account sees network-specific data (1st/2nd/3rd degree connection status, mutual connections) that a third-party account cannot see.
This Is Industry Standard: All LinkedIn automation tools (Lemlist, Expandi, Dripify, LinkedHelper, PhantomBuster, etc.) work the same way — they use your own LinkedIn account to fetch profile data. There is no technical alternative that does not risk account bans.
How We Protect Your Account:
Conservative daily caps (10-100 profiles/day depending on account age)
Random delays between profile views (2-5 seconds) to mimic human behavior
Dedicated proxy per account so your LinkedIn traffic comes from a consistent IP
Circuit breaker stops all activity if errors are detected
Rate limits shared with campaign actions to prevent exceeding safe thresholds
Bottom Line: Using your own account for enrichment is the only safe and sustainable approach. The alternative — a shared scraper account — would get banned quickly and provide inferior data (no connection degree information). WarmySender's conservative rate limits ensure your account stays safe while enrichment runs in the background.
Yes — you can start a LinkedIn campaign immediately without waiting for enrichment to complete.
What Campaigns Need: LinkedIn campaigns only require LinkedIn profile URLs to function. When you create an audience (from search, CSV import, or manual entry), each profile has a LinkedIn URL. This is all the system needs to send connection requests, messages, and InMails.
What Enrichment Adds: Enrichment fetches additional profile details — first name, last name, headline, company, location, and job title. These are used for personalization merge tags in your campaign messages (e.g., {{firstName}}, {{company}}, {{headline}}).
What Happens Without Enrichment:
Connection requests are sent normally — LinkedIn uses the profile URL, not enriched data.
Messages and InMails are sent normally — the prospect's LinkedIn identity is resolved from their URL.
Merge tags for unenriched profiles will be empty unless you set fallback values.
Use Liquid syntax fallbacks: {{firstName | default: 'there'}} renders as 'there' if the name is not yet enriched.
Recommended Workflow for Large Audiences:
Import your audience (e.g., 1,000 profiles from a Sales Navigator search)
Start enrichment in the background (LinkedIn > Audiences > Start Enrichment)
Create your campaign immediately — do not wait for enrichment
Launch the campaign — it will process prospects using available data
As enrichment completes for each profile, the additional data becomes available for subsequent campaign steps
This parallel approach means you are running your campaign and enriching at the same time — no wasted days waiting.
When Enrichment Does Matter: If your campaign strategy heavily relies on personalization (e.g., mentioning the prospect's company or headline in your invite note), you may want to wait for at least partial enrichment. But even then, you can start the campaign and the first prospects processed will be those with available data.
If your Dashboard Health Score is dropping even though your per-mailbox warmup scores are high (e.g., 100), the issue is likely in your campaign performance or LinkedIn account status — not warmup.
The Dashboard Health Score is a composite metric that combines warmup health (30-40% weight), email campaign performance (40-50% weight), LinkedIn health (20% weight), and campaign status (10% weight).
Most common causes:
Low campaign open rates — If you recently started email campaigns on new or under-warmed domains, open rates may be below 20%. The email sub-score penalizes open rates below 20% heavily. Solution: Warm up mailboxes for at least 2-3 weeks before launching campaigns. Write better subject lines and start with small volumes.
Zero reply rate — New campaigns with no replies yet get a low reply score. This is normal for the first few days. As replies come in, the score will improve.
LinkedIn account needs verification — If your LinkedIn account status changed to 'needs_verification' or is restricted, the LinkedIn sub-score drops significantly. Check LinkedIn > Accounts and reconnect if needed.
Missing DNS records — If SPF or DKIM is not configured on some mailbox domains, the warmup sub-score is penalized. Check Analytics > Mailboxes for DNS status.
What to do:
Check which sub-score is low: look at the dashboard insights for specific recommendations.
If campaigns are new, give them time — the score will improve as engagement data accumulates.
If LinkedIn is the issue, reconnect your LinkedIn account.
Ensure all domains have proper SPF, DKIM, and DMARC configured.
See the 'Understanding the Dashboard Health Score' guide for full details on how the composite score works.
If your Analytics page shows no data or appears empty, check the following:
Account age — If your account is very new (less than 3-7 days old), there may not be enough data to display meaningful analytics. Warmup analytics require at least a few days of warmup activity. Campaign analytics require sent emails with tracked events (opens, clicks, replies).
Date range — The Analytics page defaults to a 30-day date range. If your account is newer than 30 days, all your data should be within this range. Try switching between 7d, 14d, and 30d date ranges using the dropdown at the top of the page.
Active tab — The Analytics page has multiple tabs (Overview, Campaigns, Mailboxes, Templates, Segments, Warmup, Deliverability, LinkedIn). Each tab loads data independently. Make sure you are on the correct tab for the data you expect to see.
No campaigns running — The Overview tab primarily shows campaign email metrics (sent, opened, replied, bounced). If you have not sent any campaign emails yet, the overview will show zeros. Warmup data appears on the Warmup tab.
Warmup tab specifically — The Warmup analytics tab shows data from the warmup_daily_stats table. If warmup has been running for less than 2-3 days, charts may appear sparse. This is normal — data populates as warmup activity accumulates.
Warmup stats update frequency — Warmup health scores and inbox/spam rates are recalculated approximately every 6 hours by a background scheduler. If you just enabled warmup, wait for at least one stats update cycle.
Browser cache — Try a hard refresh (Ctrl+F5 or Cmd+Shift+R) to force reload the page data.
Subscription required — Some analytics features require an active paid subscription. Check your Billing page for subscription status.
If analytics still show no data after 7+ days of active warmup and campaign sending, contact support at hello@warmysender.com.
If you see prospects marked as 'Failed' with the error 'Failed: stuck in processing loop after 3+ recovery cycles', this means the system tried to send an email to the prospect three times but could not complete the send each time.
Why this happens:
Your mailbox hit its daily sending limit — If your campaign has more prospects scheduled to send than your mailbox can handle in a day, some send jobs get stuck waiting for capacity. After 3 retries without successful delivery, the prospect is marked as failed.
Only one mailbox assigned — With a single mailbox and a low daily limit (e.g., 30/day), the system cannot process high volumes. Jobs compete for limited send slots.
Sending window too narrow — If your sending window is short (e.g., 2 hours) and many sends are scheduled, some may not get processed in time.
How to fix:
Add more mailboxes to your campaign — Go to Campaign Settings and assign 3-5 mailboxes. Use mailbox rotation (round-robin) to distribute load.
Reduce daily campaign volume — Lower your per-campaign daily send limit to match your available mailbox capacity.
Widen your sending window — A wider sending window (e.g., 8 AM to 6 PM instead of 9-12) gives more time to process all sends.
Check mailbox health — Ensure all assigned mailboxes are connected and not in error state.
Recovering failed prospects: Failed prospects can be re-enrolled in a new campaign. Export or note the failed prospect emails from your campaign detail page, fix the capacity issue (add mailboxes, reduce volume), and create a new campaign targeting those prospects.
Prevention: As a rule of thumb, your total daily mailbox capacity (number of mailboxes × daily limit per mailbox) should be at least 2x your campaign's daily send target. This ensures there is always available capacity even during peak scheduling.
When a LinkedIn or email step fails for a specific prospect, the campaign Prospects tab shows a per-prospect error pill explaining why. Most errors are temporary and resolve on the next scheduler tick — but a small set are permanent and need user action. Here is the full list:
Invite failed: HTTP 404 — LinkedIn could not find the profile. Common causes: profile deleted by the user (most common), account banned by LinkedIn, member-id changed after a profile rebrand, or rare Unipile bridge cache lag.
What to do: A single 404 can be transient and the platform will retry. After 3 consecutive 404s, the campaign detail page shows an 'Invalid prospects' banner with a one-click Exclude button. Excluding a prospect flips it to status='stopped' with reason 'Excluded: profile inaccessible (HTTP 404)', cancels any pending send jobs, and frees the daily-invite quota slot. Excluding fires zero LinkedIn API calls — it is a database-only operation, so it is safe even if the underlying account is in cooldown.
Account in cannot_resend_yet cooldown until <timestamp> — LinkedIn told Unipile your account hit its invite limit. Per Unipile's documentation, this is HTTP 422 and the platform's recommended response is to space requests at random intervals and respect LinkedIn's 80-100 invitations/day band (5/month for free accounts). WarmySender sets a 4-8h account-level cooldown so other prospects on the same account also wait — burning more sends during a throttle deepens the rejection.
What to do: WAIT. The cooldown auto-clears at the timestamp shown in the error. Do not pause and resume the campaign — that does not shorten the cooldown and adds noise. The platform takes GREATEST(existing, new) on every cooldown signal, so repeated throttles never shorten the deadline; only longer ones extend it. The job that hit the cooldown gets marked expired (terminal for that retry attempt), but the underlying enrollment is rescheduled to the cooldown end + jitter, and a fresh job mints automatically on the next tick.
Daily LinkedIn limit reached / Weekly invite limit — You sent up to your configured daily/weekly cap, which is anchored to LinkedIn's 80-100/day band and your ramp week (1-4).
What to do: WAIT. The daily cap resets at midnight UTC; the weekly cap resets Monday 00:00 UTC. Scheduler resumes automatically.
Outside sending window — The action would have fired outside your campaign's sending window (e.g. weekend, late evening).
What to do: WAIT. The job re-fires on the next valid window slot. If you want sends 24/7, edit the campaign and widen the window — but for LinkedIn, off-hour activity raises ban risk.
linkedin_account_disconnected (campaign pause) — LinkedIn cookie expired or you logged out elsewhere.
What to do: RECONNECT. Settings → LinkedIn → Reconnect. The campaign auto-resumes within 5 minutes (one scheduler tick) once the connection is healthy.
Permanently failed after 5 stuck — A processing safety valve fired. Usually caused by 5 consecutive transient blockers (disconnected account, daily-cap hit, sending-window starvation).
What to do: RECOVER. The campaign detail page shows a 'Stuck prospects' orange banner with a Recover button — click it once the underlying issue is resolved (account reconnected, capacity added, etc.).
For the full HTTP 404 troubleshooting and cooldown deep-dive (including Unipile's official guidance), see the 'Why prospects might fail and how to fix' section at /documentation#prospect-failures.
If the Endorse Skill campaign step is being skipped for some prospects, it means those prospects have no endorsable skills on their LinkedIn profile. This can happen when:
The prospect has not listed any skills on their profile
The prospect's skills don't have endorsement IDs (rare technical issue)
The prospect's profile is restricted or not fully visible to your account
When this happens, the step advances to the next one automatically — it does not fail the enrollment. This is by design to ensure your campaigns continue smoothly.
If you specified a preferred skill name in the step configuration and it wasn't found, the system endorses the first available skill instead.
To verify: Check the enrollment's event log for a 'skill_endorsed' event. If missing, the step was skipped due to no available skills.
LinkedIn only allows message deletion within 60 minutes of sending. After this window, the delete button is hidden and the server will reject deletion attempts.
This is a LinkedIn platform limitation, not a WarmySender restriction. The 60-minute window is enforced both in the UI (the delete button only appears for messages sent within the last hour) and on the server (the API returns a 'DELETE_WINDOW_EXPIRED' error if you try to bypass the UI).
If you need to address a sent message after the 60-minute window:
Send a follow-up correction message
If the message was to a campaign prospect, you can adjust the campaign steps for future enrollments
Tip: Review your message templates carefully before launching campaigns to minimize the need for message deletion.
If your main subscription is canceled or becomes inactive, your LinkedIn add-on is also affected:
All connected LinkedIn accounts will be disconnected
All active LinkedIn campaigns will be paused
Your LinkedIn seats will become inactive
The LinkedIn add-on cannot operate independently — it requires an active paid subscription. If you re-subscribe, you can reconnect your LinkedIn accounts and resume campaigns.
Note: Canceling only the LinkedIn add-on does NOT affect your email plan. Your email campaigns, warmup, and other features will continue working.
If you see an Open Rate or Click Rate above 100% anywhere in the platform, here is what is happening and how we handle it.
What Causes Inflated Rates Email security scanners such as Microsoft SafeLinks, Mimecast, Proofpoint, and Gmail's own link preview services automatically pre-fetch every link and tracking pixel in incoming email to check them for malware and phishing. They do this with non-human user-agents, often before the recipient has even seen the message. Each pre-fetch can register as an open or click in raw tracking data, which artificially inflates the counters.
In some environments, a single email can trigger 2-3 scanner opens and 3-5 scanner clicks before a human ever touches it — which is how raw open or click counts can exceed the number of emails sent.
How WarmySender Filters Scanners We filter these security scanners out at the tracking endpoints by matching known scanner user-agents, IP ranges, and request patterns. Filtered events are excluded from your displayed numbers so you get accurate metrics instead of raw counters.
100% Safety Cap As an additional safety guard, displayed Open Rate and Click Rate values are capped at 100%. You will never see '127%' shown in the UI — even if raw data were temporarily off, the display clamps to 100%.
If You Still See Inflated Numbers If a campaign shows a rate suspiciously close to or at 100% and you think something is off, the most common cause is recent re-enrollment of prospects. When you re-enroll prospects into a campaign, the original tracking links from previous enrollment cycles can still fire if a scanner pre-fetches them later. This can make it look like a single send is generating multiple events.
Recommendation: Trust Reply Rate We recommend treating Reply Rate as your primary engagement metric. Replies are not faked by scanners — they come from real humans who actually read your message. Open Rate and Click Rate are useful directional signals, but Reply Rate is the number that reflects real interest in your outreach.
When a prospect replies to one of your campaign emails with an Out of Office message, WarmySender handles it automatically so your sequence is not accidentally ended.
Automatic Detection in 5 Languages We auto-detect Out of Office replies in English, Dutch, German, French, and Spanish. The system scans incoming replies for common Out of Office phrasing and headers in each language and classifies them accordingly.
Out of Office Does NOT Terminate Enrollment An Out of Office reply is treated as 'the lead is on vacation, not rejecting you'. It does not stop the sequence. The campaign automatically resumes its sequence for that lead once they return and the normal scheduling kicks back in — so you do not lose the lead, and you do not accidentally burn the follow-up by treating a vacation bounce as a real reply.
If We Miss an Out of Office (Rare) Occasionally a reply uses very unusual phrasing that the detector misses (for example, an internal custom auto-reply in a language we do not yet support). If you spot one in your inbox and it was classified as a normal reply, you can fix it manually:
Open the Unified Inbox and click the reply in question
Change the sentiment to 'Out of Office'
Save
As soon as you mark the reply as Out of Office, the campaign immediately resumes its sequence for that lead.
What Happens Next Leads marked as Out of Office return to Pending status and pick up their next sequence step on the next scheduler tick. You do not need to re-enroll them or take any further action — the system will continue the sequence automatically on schedule.
Best Practice If you notice a specific phrasing the detector keeps missing, report it to support so we can improve coverage. Out of Office detection is continually refined based on real-world examples.
All paid plans (Pro, Business, and Enterprise) include UNLIMITED mailboxes. There is no cap on the number of email accounts you can connect, and no per-mailbox fee. You can warm up as many mailboxes as you want at no additional cost.
Mailbox limits only apply to unpaid tiers:
Free tier: 1 mailbox
All paid plans (Pro $14.99/mo, Business $29.99/mo, Enterprise $69.99/mo): Unlimited mailboxes
This means on the Pro plan at $14.99/month, you can connect 5, 50, or 500 mailboxes — there is no limit. Email warmup runs on all connected mailboxes simultaneously. Your only constraint is your monthly email quota (e.g., 10,000/month on Pro), which is shared across all mailboxes and all sending activity (warmup + campaigns).
Team members refers to the number of people who can access your WarmySender workspace. Each member gets their own login account.
Pro plan: 2 members — this means you (the workspace owner) plus 1 invited team member
Business plan: 4 members — you plus 3 invited team members
Enterprise plan: 4 members — you plus 3 invited team members
Team members are NOT mailboxes. Mailboxes (email accounts you connect for warmup/campaigns) are unlimited on all paid plans. Members are the people who log in to manage your campaigns.
IMPORTANT: Connecting a mailbox does NOT use a team member seat. You can connect unlimited email accounts (mailboxes) to your workspace without inviting anyone. For example, if you have 6 domains with 3 email addresses each (18 mailboxes total), you can connect all 18 to a single workspace and manage them entirely on your own — no additional team members needed. The Pro plan at $14.99/month is all you need.
Each invited member can be assigned a role:
Admin — Full access except billing management
Member — Create campaigns, manage prospects, view analytics
Viewer — Read-only access to all data
To invite a team member: Go to Settings > Team tab > Click 'Invite' > Enter their email and select a role. Pending invitations count toward your member limit.
If you need more than your plan allows, upgrade to Business ($29.99/mo) for 4 members, or contact support for custom needs.
Yes! You can connect mailboxes from as many domains as you want into a single workspace. There is no domain limit and no per-mailbox fee on any paid plan.
Example scenario:
You have 6 domains (e.g., acme.com, acmesales.com, acmeio.com, etc.)
Each domain has 3 email accounts (e.g., john@, sales@, info@ on each)
That is 18 mailboxes total
You can connect all 18 to ONE workspace on the Pro plan ($14.99/month) and manage them entirely by yourself
Key points:
Mailboxes are email accounts you connect — they are NOT the same as team members or seats
Connecting a mailbox does NOT require a team member seat
A single workspace owner can connect and manage unlimited mailboxes alone — no need to invite anyone
Team member seats (Pro: 2, Business: 4, Enterprise: 4) are only for inviting other people who need their own login to help manage the workspace
All connected mailboxes share your plan's monthly email quota (Pro: 10,000/month, Business: 100,000/month, Enterprise: 300,000/month)
Each mailbox can be independently assigned to campaigns and warmup
When to use multiple workspaces instead:
You are an agency managing separate clients who should not see each other's data
You want completely isolated campaigns, prospects, and analytics per business unit
Multiple workspaces are available on Business (up to 3) and Enterprise (up to 5) plans
You keep access until the end of your current billing period
LinkedIn accounts are disconnected and campaigns paused only after the billing period ends
IMPORTANT: LinkedIn seats require an active paid email subscription. If your main subscription (Pro/Business/Enterprise) is canceled or becomes inactive, your LinkedIn accounts will be disconnected and LinkedIn campaigns will be paused — even if your LinkedIn seat subscription is still active. The LinkedIn add-on cannot function without a base email plan.
Canceling only the LinkedIn add-on does NOT affect your email plan or email campaigns.
You can apply a promo code when subscribing or when changing your plan.
During initial checkout:
When you click 'Subscribe' on a plan, the Stripe checkout page has a field for promo/coupon codes
Enter your code before completing payment to see the discounted price
When changing plans (existing subscribers):
Go to the Billing page
Click 'Change Plan'
Select your new plan
Enter your promo code in the promo code field
The discounted price and any proration will be shown before you confirm
Note: Promo codes may have usage limits, expiry dates, or restrictions on which plans they apply to. If a code is not working, it may have expired or reached its usage limit. Contact support at hello@warmysender.com for assistance.
Yes! WarmySender offers both monthly and annual billing. Annual plans save you 40% compared to monthly pricing as part of a limited-time evergreen offer.
Annual Pricing (billed yearly, save 40% — limited time):
Pro: $8.99/month ($107.88/year) — save 40%
Business: $17.99/month ($215.88/year) — save 40%
Enterprise: $41.99/month ($503.88/year) — save 40%
Monthly Pricing:
Pro: $14.99/month
Business: $29.99/month
Enterprise: $69.99/month
How the limited-time 40% annual offer works:
The 40% discount is evergreen but framed with a real end-of-month deadline that resets monthly. The date you see counting down is the actual end of this calendar month UTC, but the discount itself does not actually disappear when the date hits — the urgency framing rolls forward.
Existing annual subscribers (pre-2026-04-29) keep their original 25% price — they are grandfathered at the rate they signed up for and renew at that same price ID until they cancel or switch tiers.
Promo codes can stack on top of the 40% (a 10% off code at checkout makes the total ~46% off list price).
LinkedIn seats are unaffected — they remain monthly-only at $9/seat/month per workspace.
You can switch between monthly and annual billing from the Billing page. All prices are in USD. Cancel anytime — you keep access until the end of your paid period.
Go to the Mailboxes page, open the row's dropdown menu, and click 'Edit Daily Limit' (also available from the mailbox's View Details page). Enter the new value and save — the change is live on the next scheduler tick. You do NOT need to disconnect or reconnect the mailbox, and no campaigns are disrupted.
Remember the MIN-of-three rule: sending is capped by the MINIMUM of the mailbox's daily limit, the campaign's dailySendLimit, and the campaign-mailbox maxSendsPerMailboxPerDay — whichever cap is hit first stops sends. Warmup volume is tracked separately and is not affected by this setting.
This was a real bug — fixed Apr 30, 2026 (LL#252). Earlier, four code paths could write status='paused' on a LinkedIn campaign row without also writing the paused_at timestamp and paused_reason columns. Campaigns paused that way were invisible to the auto-resume sweeper and stayed paused forever, even after the underlying issue (account disconnect, high failure rate, etc.) cleared.
The fix introduces a canonical pauseLinkedinCampaign helper that flips all three columns atomically under a same-transaction audit row, plus a Postgres CHECK constraint that rejects any future regression at the DB layer.
What you should see now:
Open the campaign detail page and look at the new paused_reason field — it now always tells you why the pause happened (e.g. linkedin_account_disconnected, linkedin_high_failure_rate, subscription_canceled, manual_pause).
If your campaign predates the fix and the field is still empty, click Resume once and the system will re-evaluate the row through the canonical helper, populate paused_reason if there is a real cause, or move it back to running if not.
Your prospects, sequences, and analytics are completely untouched by the fix — it is pure metadata hygiene.
If Resume immediately re-pauses with a populated reason, the underlying issue is real (e.g. account is genuinely disconnected) — fix that root cause and Resume again.
Sales Navigator URLs (the form linkedin.com/sales/lead/ACoAAA...,NAME_SEARCH,XYZ) sometimes can't be resolved to a public LinkedIn member ID. This happens for restricted profiles, recently-deleted leads, and a known Unipile-side bug with certain ,NAME_SEARCH, query suffixes.
Before Apr 30, 2026, when resolution returned null, our campaign engine treated the prospect as 'cannot be invited, mark complete' — silently burning the prospect with linkedin_status='completed' and zero invite attempt. As of LL#253, affected prospects now show linkedin_status='unresolved_url' (a new status value) and the engine retries with exponential backoff up to 5 times before promoting to terminal failed. They never burn silently again.
To recover prospects affected by the old behavior:
Best path: re-import them with regular linkedin.com/in/<handle> URLs. The public-handle form resolves reliably across all Unipile resolver code paths.
If you have many affected prospects, contact support — we can run the un-burn backfill script which automatically re-stamps eligible prospects to unresolved_url so they re-enter the queue on the next campaign tick.
Your campaign config and other prospects are untouched. The Talha customer case (Apr 30, 2026 — 264 of 412 prospects, 64% loss) drove the discovery and the fix.
No, the counter is correct. WarmySender ships two LinkedIn campaign engines that both increment invites_sent_week on your account: the legacy standalone engine (LinkedIn-only campaigns) and the unified multichannel engine (campaigns combining email and LinkedIn steps). Both engines hit the same atomic counter, but the journal rows land in different tables — linkedin_campaign_enrollments for standalone and campaign_prospects for unified.
If the dashboard's per-campaign count looks lower than the counter, you're likely viewing a standalone campaign while the missing invites came from a unified multichannel campaign on the same account, or vice versa. The counter is the single source of truth for rate-limit gating, so it is never wrong.
As of Apr 30, 2026 (LL#254), the engineering audit query was fixed to join BOTH journal tables via the 2-hop campaigns.linkedin_account_id path; eight customers were briefly misdiagnosed as having a 'cap-leak' before the fix shipped — none of them actually did.
To see total invites across both engines for an account, the LinkedIn Accounts dashboard now shows invites_sent_week / weekly_limit directly from the counter (engine-agnostic). If the numbers still don't add up after a 5-minute refresh, contact support — we can run the canonical 2-hop diagnostic.
This was a real bug — fixed Apr 30, 2026 (LL#255). Reply detection on the LinkedIn side relies on a column called enrollment_id on every inbound message row, but every inbound linkedin_messages row written by the Unipile webhook ingest path (and the polling fallback) was being persisted with enrollment_id=NULL because neither path performed the canonical enrollment lookup before the INSERT.
Net: every inbound LinkedIn message landed in the database with no campaign attribution, every downstream reader (the linkedin_replied_at stamp on campaign_prospects, the auto-stop-on-reply check, the analytics reply-rate roll-up) silently filtered it out, and the dashboard showed 0 replies even when prospects had clearly responded. The worst part: campaigns kept sending follow-ups to prospects who had already replied.
The fix adds a canonical lookupEnrollmentForInboundMessage helper that the webhook handler and the poller fallback BOTH call before the INSERT — so every inbound message is now correctly attributed to its enrollment if one exists. We also ran a one-shot 120+ row backfill that retro-fits the lookup against historical NULL rows.
What you should see now:
Reply stats refresh within 1 hour after the backfill runs (the analytics roll-up reads on a 1h cadence).
Campaigns auto-stop on first reply, so any follow-up that was queued but not yet sent will be cancelled when the backfill stamps the historical reply.
If you still see drift after that 1-hour window, contact support — we can re-run the backfill against your specific workspace.
Going forward, every inbound LinkedIn message is correctly attributed at write time, so this regression cannot recur. A CI grep test rejects any new INSERT INTO linkedin_messages outside the canonical helper file as defense in depth.
No — Apr 30 fix (LL#256). Previously, every HTTP 422 response from Unipile / LinkedIn (the surface that includes 'Profile inaccessible' as a customer-facing error) was inline-stamped status='failed' and the prospect was burned with no further retry — even though the LinkedIn 422 surface conflates several semantically-distinct cases, including some that are fully recoverable on a re-resolve:
Sales Navigator URLs that didn't resolve on attempt N but resolve cleanly on attempt N+1.
URL canonicalization issues fixed by the LL#253 provider_id-aware fallback.
Transient resolver issues that clear within minutes.
The platform-wide audit found 21,868 enrollments burned this way.
The fix migrates all 422 dispositions to the LL#253 defer-not-burn template:
The prospect's status flips to 'pending_resolution' (a new value) instead of terminal 'failed'.
The engine retries with exponential backoff capped at 5 attempts before promoting to terminal 'failed'.
The 21,868 historical rows were swept into the same recovery flow with their re-attempts spread over a 24-hour window so the queue doesn't slam LinkedIn rate limits.
What you should do:
If you see this status on individual prospects: please verify the prospect's LinkedIn URL is current. Regular linkedin.com/in/<handle> URLs resolve most reliably across all Unipile resolver code paths.
Click Retry on the prospect detail page if you want to force an immediate re-attempt (otherwise the defer flow handles recovery automatically).
If a prospect repeatedly lands back in 'pending_resolution' after 5 retries, that's a genuinely-terminal restricted profile — the engine will promote it to terminal 'failed' at that point, and you can safely exclude or remove them.
No manual un-burn is needed for the 21,868 historical cohort — the backfill handled it automatically.
This is a real bug — fixed Apr 30, 2026 (LL#258). Previously, if your campaign template referenced a custom variable like {{custom.Linkedinconnection}} and your imported CSV didn't have that column (typo, missing column, capital-letter mismatch), the campaign engine had two failure modes:
Pre-LL#235: render the message with a literal 'undefined' and send anyway (rude, kills reply rates).
Post-LL#235: burn the prospect with a terminal status='failed' and last_error='template_variable_unresolved' (irrecoverable without manual operator intervention).
Customer Humair Ali hit this — 9 of 15 prospects silently failed before he noticed. The fix is two-layer:
(1) Validate-at-launch — the campaign launch path now enumerates every {{custom.<name>}} reference in your template, intersects against the actual column set in your prospect data, and BLOCKS launch with an actionable error if any references aren't satisfiable. The error names the missing column AND lists every column that DOES exist in your prospect data, so you can immediately see whether you have a typo (capital L vs lowercase l, missing s, etc.) or a genuinely-missing column.
(2) Defer-at-send — if a template variable somehow still unresolves at send time (race: campaign launched against audience N, then audience N had a column dropped before the send fired), the runtime renderer now writes linkedin_status='pending_template_variable_resolution' instead of a terminal failure. The prospect re-enters the queue on the next campaign re-evaluation, so once you fix your template OR re-import the CSV with the corrected column, the affected prospects retry automatically — no manual un-burn needed.
How to fix this on existing prospects:
Option A — edit your template to remove the missing variable. Save the campaign. Click Resume. Affected prospects retry on the next campaign tick.
Option B — re-import the CSV with the column populated (or rename the column to match your template's spelling). Click Resume. Affected prospects retry.
Option C — if you used a typo (capital L on Linkedinconnection but your CSV has lowercase linkedinconnection), the simplest fix is to edit the template to use the lowercase name, save, and click Resume.
No LinkedIn API calls were made for the affected prospects (the deferred renderer doesn't touch LinkedIn), so there's no rate-limit cost to retrying.
If your dashboard is missing recent LinkedIn replies even though prospects are clearly replying on LinkedIn, the most likely cause is an upstream webhook outage at our integration partner Unipile.
First, the important thing: every reply is still safely in your LinkedIn inbox — nothing is lost on LinkedIn's side. The gap is purely between Unipile and WarmySender, NOT between you and your prospect.
How the signal flows: Prospect replies on LinkedIn → LinkedIn delivers to Unipile → Unipile webhook (linkedin.reply_received) → WarmySender stamps the reply on your dashboard.
When Unipile's webhook delivery stalls, the inbound message still reaches our database via a 30-minute polling fallback, but the platform-side side-effects that the webhook normally triggers (the linkedin_replied_at stamp on your prospect, the auto-stop-on-reply check, the Slack/n8n/Zapier reply notification, and the dashboard reply counter) only fire when the webhook handler runs. So during the outage you may see follow-ups continue on threads where the prospect has already replied.
Difference between platform-side and Unipile-side:
Platform-side (under our control) — DB writes for state-flip, dashboard counters, Slack/n8n/Zapier emit, auto-stop-on-reply. We have a 15-minute health monitor (Apr 30, 2026 Layer F1) that detects when webhook freshness drops below threshold and inserts a webhook_outage admin alert with kind='linkedin_reply_received_outage_suspected'.
Unipile-side (their job to fix) — actual webhook delivery from LinkedIn through to our /webhooks endpoint. When Unipile's delivery stalls, our operator pages Unipile support via their support channel.
What WarmySender does during the outage:
The 15-minute webhook health monitor fires a critical-severity admin alert within one tick of the outage starting.
The 30-minute polling fallback (syncAccountConversations in the LinkedIn scheduler) pulls inbound rows from Unipile via LIST and writes them into linkedin_messages — so we keep a complete record of what arrived. This is bridging cover, not a fix.
Once Unipile restores webhook delivery, an operator runs an idempotent replay backfill that walks every inbound row that landed since the outage start and re-drives the missed state-flips through the canonical markProspectReplied helper. This retroactively stamps linkedin_replied_at on your prospects, fires the auto-stop-on-reply check, wakes any parked wait_reply or condition_linkedin_replied steps, and emits the missed Slack/n8n/Zapier notifications. The replay is idempotent — running it multiple times is safe.
What you can do as a customer:
Reassurance: replies are not lost. Open the actual LinkedIn inbox to read them while waiting.
If you have time-sensitive threads, manually pause the affected campaigns until the dashboard catches up — this prevents follow-ups from going out on already-replied threads during the outage window.
Once recovery completes (typically within 1 hour of Unipile fix + replay run), your dashboard reply counters will reflect ground truth and stop-on-reply will have been retroactively applied.
If you suspect this is happening to your workspace, contact support at hello@warmysender.com with a sample prospect URL and approximate reply timestamp; we can verify the per-account state and confirm the recovery timeline.
No Unipile API calls are made from the F1 detection or replay layer — account safety always wins. The platform's job during a webhook outage is detection + bridging via the polling fallback + replay on recovery; the Unipile-side fix is the operator's responsibility per the runbook.
If a prospect's LinkedIn invitation was accepted but they never received the configured follow-up message, you're hitting one of three scenarios. We have specific recovery flows for each one — no prospects are permanently lost.
Scenario 1 — the LinkedIn account was disconnected at the moment the follow-up was supposed to fire. The campaign engine cannot send a LinkedIn message through a disconnected account (account safety always wins), so it parks the enrollment with linkedin_status='paused_account'. As soon as you reconnect the LinkedIn account, the platform's auto-resume sweep wakes the parked enrollments and the follow-up goes out on the next sending tick. No manual action is needed beyond reconnecting the account.
Scenario 2 — the follow-up step was a 'wait for acceptance' condition that already evaluated and routed the prospect down the false branch. This happens if the wait window expired before the acceptance webhook landed. The prospect is in the campaign's correct end state per how you configured the campaign — they aren't stranded, they were routed per the false branch you defined.
Scenario 3 — silent skip from a worker race condition or a campaign edit mid-flight. This is the genuinely-stuck pattern. Symptom: linkedin_accepted_at is set, status='completed', last_messaged_at is NULL, no error event. We ship a periodic post-acceptance enqueue helper (LL#233 enqueuePostAcceptanceNextStep) and an orphan-job-reconciler Sweep B that catches these rows and recreates the missing send_message job. On Apr 30, 2026 (Layer F10) we ran a one-shot backfill against a 422-row Vishwanath cohort — 28 rows were paused_account (Scenario 1, waiting on reconnect) and 389 were investigated for silent-skip; a fraction had genuinely been routed by an in-flight campaign edit (Scenario 2, no action needed) and the remainder were re-armed via the resume sweep.
What to do:
Check the LinkedIn account status — if any account on the campaign shows 'Reconnect needed', click Reconnect, then wait 5-10 minutes for the auto-resume sweep.
Check the campaign's step configuration — did your wait window expire? Did you edit the campaign mid-flight and remove a step? The campaign card shows the current configuration.
If the prospect's enrollment shows linkedin_accepted_at set, status='completed', and last_messaged_at is NULL — and you HAD a configured follow-up — contact support at hello@warmysender.com with the prospect URL. We can manually re-arm the enrollment.
No Unipile API calls are made from the recovery flows — every gate (window clamp, per-account ramp, daily cap) is preserved on the rewake.
Replies imply acceptance — a prospect can't reply to your message unless they accepted the invite first. If your campaign shows replies but the accept counter is 0, you're hitting one of two issues.
Issue 1 — fast-reply race (already fixed Apr 27, 2026 in LL#204). When a prospect accepted and replied very quickly, the old code path stamped linkedin_replied_at but skipped the linkedin_accepted_at stamp because the row had already advanced past 'invited'. The dashboard tile counted accepts via linkedin_accepted_at IS NOT NULL, so the counter under-reported. The fix split the timestamp stamp from the status flip so even a fast-reply row gets its acceptance recorded forensically.
Issue 2 — invite_accepted event mirror gap (fixed Apr 30, 2026 in Layer F5 / LL#262). Some analytics surfaces (the 24h freshness banner on LinkedIn → Accounts, the per-account analytics roll-up) read the legacy linkedin_events table for event_type='invite_accepted'. After the Apr 27 helper consolidation, unified-engine campaigns wrote acceptance events to a different table (campaign_events) but never mirrored to linkedin_events. So the 24h freshness banner showed 'no accepts in 24h' even when accepts were flowing. The fix adds a paired insert into linkedin_events from the canonical helper, idempotent on duplicate webhook+polling signals.
What the dashboard counters actually mean now:
Campaign-card 'Accepted' counter — reads campaign_prospects.linkedin_accepted_at. Source-of-truth for acceptance rate.
Campaign-card 'Replied' counter — reads campaign_prospects.linkedin_replied_at. Source-of-truth for reply rate.
LinkedIn → Accounts 'last 24h activity' freshness banner — reads linkedin_events. Now mirrored from the canonical helper after Apr 30.
If you still see the issue:
Wait 1-2 hours after Apr 30 deploy for the optional one-shot backfill to land (it covers the Apr 24 → Apr 30 hole on the linkedin_events table).
Hard-refresh your dashboard — the counter is cached for 60 seconds.
If the accept rate still shows 0% after the deploy date and you have replies, contact support at hello@warmysender.com.
No Unipile API calls are involved in the counter — every fix is a DB-state hygiene fix on signals we already received.
This error means your campaign's message template has a Liquid template syntax error — most commonly a typo in a merge tag like {{company} (one closing brace instead of two) or {{first_name} (same shape).
Why this happens: Liquid is the merge-tag rendering engine that powers personalization. Every variable reference must be wrapped in EXACTLY two opening braces and two closing braces: {{firstName}}, {{company}}, {{custom.subject_line}}. If you accidentally type one closing brace instead of two, LiquidJS throws a parse error at send time.
Before Apr 30, 2026 (Layer F7), this triggered an infinite retry loop — the engine would catch the error, mark the job 'failed', the orphan reconciler would resurrect the enrollment, and the new job would hit the same parse error. Customer Selva's PIPL Connection campaign had 28 send_message jobs retrying continuously with the same '{{company}' typo until we shipped the dead-letter fix.
After Apr 30, 2026:
The engine detects the parse-error signature on the first attempt.
The send_job is marked status='failed' with last_error_classification='template_syntax_error' so the dashboard banner can surface the typo.
The enrollment is parked with linkedin_status='pending_template_fix' so the orphan reconciler does NOT recreate the job.
The error message is customer-friendly: 'Template syntax invalid — please fix the template and resume'.
How to fix: 1) Open the affected campaign in the editor. 2) Find every merge-tag reference and verify each one has exactly TWO opening braces and TWO closing braces. Common typos: • {{firstName} → fix to {{firstName}} • {firstName}} → fix to {{firstName}} • { {firstName}} → fix to {{firstName}} (no space between the braces) • {{firstName | default: 'there'} → fix to {{firstName | default: 'there'}} 3) Click 'Save' on the campaign. 4) Click 'Resume' on the campaign card. Affected prospects retry on the next campaign tick. 5) The dashboard banner clears within 1-2 minutes.
No prospects are lost — they sit in pending_template_fix until you fix the template and resume. No LinkedIn API calls were made on the failed attempts (the parse error fires BEFORE the Unipile call), so there's no rate-limit cost to retrying.
If you're not sure where the typo is, click 'Preview' in the campaign editor — the preview will fail with the exact line number of the parse error.
If the LinkedIn → Accounts page shows a different daily count than what your campaign card reports — for example, account shows 'invites sent today: 1' but you can see 24 messages went out per the campaign's activity log — you're hitting a counter desync, not a real send failure. Every message DID go out; the counter on the account-level dashboard tile is just under-reporting the unified-engine sends.
Why this happens (LL#254 + LL#261, Apr 30, 2026): There are two campaign engines under the hood — the legacy STANDALONE engine (`linkedin_campaigns` + `linkedin_campaign_enrollments`) and the newer UNIFIED multichannel engine (`campaigns` + `campaign_prospects`). Both engines call the same atomic counter for weekly rate-limit gating (linkedin_accounts.invites_sent_week — this is correct and load-bearing for safety, never under-reports), but the daily-bucket tiles (invites_sent_today, messages_sent_today, connections_today) are written by a separate post-success increment that the unified engine forgot to wire on some action sites.
What's correct vs what's wrong:
✅ Weekly counter (drives rate-limit gating) — always correct. Your account is never sending past your configured limits.
✅ Campaign-card daily counter (driven by campaign_events / campaign_prospects) — always correct. This is the source-of-truth for 'how many messages went out today on this campaign'.
❌ Account-card daily counter (driven by linkedin_accounts.{action}_today) — under-reports for unified-engine campaigns until LL#261 fix is deployed.
How to verify the messages actually went out:
Open the campaign card and check the per-step activity counter — it shows ground-truth from campaign_events.
Open the LinkedIn inbox for the account and confirm the messages are visible in your sent items.
Open the prospect's enrollment row and check linkedin_messaged_at (set when the message landed) and last_linkedin_action_at (set when any action ran).
What we're shipping: The LL#261 fix audits every unified-engine LinkedIn action site and adds the paired daily-counter increment in the same transaction as the success event-row insert. A one-shot backfill recomputes the daily buckets from the ground-truth event rows for the desync window.
For customer Panagiotis specifically (Vishwanath account): the dashboard showed messages_sent_today=1 on Apr 30 morning even though 24 messages had legitimately gone out via the unified-engine. Every send was real, every safety gate held, the counter just lagged.
If your counters still mismatch after the fix lands, contact support at hello@warmysender.com with the account email and approximate timestamp range — we can recompute the bucket from event rows.
Why my campaign appears stuck
Common causes
Account safety wins over speed. LinkedIn outreach respects daily and weekly caps that scale with a 4-week ramp; week 1 caps are intentionally low to protect the account from a permanent ban.
Step wait days are honored. A 7-day wait between two LinkedIn steps means 7 calendar days will elapse before the next action — the system executes campaigns exactly as configured, with no auto-shortcuts.
Sending window clamping. Each campaign has a sending window (e.g. Mon-Fri, 09:00-17:00). Actions scheduled outside this window are deferred to the next valid slot.
Account disconnected. If the LinkedIn cookie expires, the campaign auto-pauses with reason linkedin_account_disconnected. Reconnect the account in Settings › LinkedIn — the campaign resumes within one scheduler tick (5 minutes).
Transient stuck-processing storm. A historical bug between Apr 21-27, 2026 left some send jobs with very long retry backoffs; recovery scripts have been run platform-wide and the underlying cause is fixed.
How to verify in the UI
Open the campaign and check the status pill. running means active; paused shows a reason.
In the campaign detail view, look at Next Action for each prospect — the timestamp is the actual next attempt time after sending-window and ramp clamping.
On the LinkedIn account card, check ramp week (1-4) and remaining daily / weekly headroom.
Open the Activity tab on a prospect for the full audit trail of attempts and errors.
How LinkedIn webhooks work end-to-end
Configuration
Settings › Webhooks › New Webhook. Paste your endpoint URL (Slack Incoming Webhook, Zapier Catch Hook, n8n / Make HTTP Trigger, or your own HTTPS endpoint).
Pick the events: linkedin.invite_accepted, linkedin.message_sent, linkedin.reply_received, linkedin.account_disconnected. Subscribe to * for everything.
Click Test webhook — WarmySender fires a sample linkedin.invite_accepted payload to your URL.
{
"event": "linkedin.reply_received",
"id": "evt_2026_04_27_dd44ee55ff66",
"occurredAt": "2026-04-27T14:08:55.211Z",
"workspaceId": "ws_abcdef0123456789",
"data": {
"campaignId": "camp_8c2f...",
"prospectId": "prs_4a7b...",
"messageBody": "Hi — yes, happy to chat next week. What works for you?",
"isFirstReply": true
}
}
HMAC-SHA256 signature verification
Every outbound webhook carries an X-Warmy-Signature header containing the lowercase-hex HMAC-SHA256 of the raw request body, keyed by your endpoint secret. Verify with constant-time compare:
// Node.js
import crypto from "node:crypto";
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) abort();
Slack-specific behavior
If your URL ends in hooks.slack.com/services/... WarmySender auto-detects it and reformats every event as a Slack Block Kit message — no custom transform needed.
Retries and dead-letter
Failed deliveries retry up to 10 times with exponential backoff (1m, 5m, 25m, 2h, 12h, capped at 72h). Each attempt is recorded in Webhooks › Logs (30-day retention). Final failures land in the workspace dead-letter queue and notify the workspace owner.
Account types and InMail credits
What each LinkedIn plan unlocks
Account type
InMails / day
Connection invites / week
Notes
Free
0 (no InMail credits)
100 / week capped by ramp
Cold messaging only via accepted connections.
Premium
25
100 / week capped by ramp
Default conservative paid tier.
Sales Navigator
50
100 / week capped by ramp
Best for cold outreach to non-connections.
Recruiter / Recruiter Lite
50
100 / week capped by ramp
Recruiter-only message templates supported.
If the account type is unknown, WarmySender defaults to Premium (a conservative paid tier) — never to Free, because Free has zero InMail credits and would silently block all InMail sends.
If an account triggers a LinkedIn restriction, WarmySender auto-switches to recovery mode with ramp_week=1 and a fresh ramp_start_date so the account re-warms safely from scratch.
Acceptance vs reply tracking
Definitions
Acceptance. The prospect clicked Accept on your LinkedIn connection invitation. linkedin_accepted_at is the moment LinkedIn marked the invite as accepted. Always fires on the first acceptance, even if the prospect replies in the same minute.
Reply. The prospect sent at least one inbound message in the LinkedIn conversation. linkedin_replied_at is the inbound message receive time. A reply forensically implies acceptance, but acceptance does not imply a reply.
Example timeline A — accept, then a follow-up message, then a reply
Day 0 09:00 Step 1 invite sent (linkedin_invite_sent_at)
Day 2 14:12 Acceptance webhook fires (linkedin_accepted_at)
Day 3 09:00 Step 2 follow-up message (linkedin_last_messaged_at)
Day 5 17:42 Inbound reply (linkedin_replied_at)
Counters at Day 5: acceptance=1, reply=1, accepted_to_reply=3d 3h
Example timeline B — reply webhook lands before acceptance webhook
Day 0 09:00 Step 1 invite sent
Day 0 09:18 Reply webhook 09:18:42; acceptance webhook 09:18:48
Both counters stamp:
linkedin_accepted_at = 09:18:48
linkedin_replied_at = 09:18:42
Even when the reply webhook lands first, the acceptance helper still stamps linkedin_accepted_at — both counters reflect reality. The status flip to connected is suppressed because replied is a strictly later state, but the stat counter is independent of the status field.