Documentation & Help Center

Complete documentation for WarmySender. Setup guides, troubleshooting, and help resources for email warmup, cold email campaigns, LinkedIn automation, and more.

Getting Started

Getting Started with WarmySender

Welcome to WarmySender! Follow these steps to get up and running:

  1. 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).
  1. 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.
  1. 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.
  1. Set up DNS records — While warming up, configure SPF, DKIM, and DMARC records for your sending domain. This is critical for inbox placement.
  1. 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.
  1. 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.

Connecting Your Mailbox

To connect a mailbox:

  1. Go to Mailboxes and click 'Add Mailbox'.
  2. Select your email provider (Gmail, Outlook, Hostinger, Zoho, etc.) or choose Custom IMAP/SMTP.
  3. Enter your full email address as the username.
  4. 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.
  5. 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.
  6. Click 'Test Connection' to verify everything works before saving.
  7. 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'.

Comparing Plans: Pro vs Business vs Enterprise

A detailed comparison of all WarmySender subscription plans to help you choose the right one.

Plan Overview (monthly billing):

Annual Billing (save 40% — limited time):

How the limited-time 40% annual offer works:

Monthly Email Quota:

Connected Mailboxes:

Email Warmup:

Team Members (Seats):

B2B Lead Database Credits (monthly, reset each billing cycle):

Email Verifier Credits (monthly, reset each billing cycle):

Prospect Storage:

Workspaces:

LinkedIn Add-On (available on any paid plan):

Features Included on ALL Paid Plans:

Enterprise-Exclusive:

How to Choose:

Free Trial: How It Works

WarmySender offers a 7-day free trial on the Pro plan — no credit card required.

What You Get During the Trial:

How to Start Your Trial:

  1. Sign up at warmysender.com
  2. Click 'Start 7-Day Free Trial' on the Pro plan
  3. No credit card needed — you get instant access
  4. Start connecting mailboxes and setting up warmup immediately

During Your Trial:

What Happens When the Trial Ends:

After Trial Expiry — How to Re-Activate:

  1. Log in to your WarmySender account
  2. You will be redirected to the Billing page
  3. Choose a plan (Pro, Business, or Enterprise) and subscribe
  4. Your account is immediately re-activated with all your data intact
  5. Paused campaigns and warmup can be resumed

Trial Limits:

Upgrading During Trial:

Available Resources & Getting Help

WarmySender provides multiple ways to learn and get help:

Documentation (You Are Here):

In-App Product Tours:

AI-Powered Help:

FAQ Pages:

Blog & Guides:

API Documentation:

Email Support:

Tip: For the fastest answers, try the AI assistant first — it has full context about WarmySender's features and can answer most questions instantly.

Quick Start: First Campaign in 15 Minutes

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.

Account Settings & Profile Management

Manage your account and workspace from Settings:

Account Tab:

Security:

Workspace Settings:

Notifications:

Data Management:

Product Tour:

Editing a Mailbox's Daily Sending Limit

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.

Reconnecting a Mailbox Without Losing Campaign Progress

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.

Email Warmup

How Email Warmup Works

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.

Warmup Settings & Ramp Modes

Each mailbox has its own warmup configuration. Go to Warmup and click on a mailbox to configure:

Ramp Speed — Controls how quickly daily volume increases:

Strategy Modes — The system uses intelligent strategies that auto-evolve based on your mailbox's age and performance:

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):

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.

How We Protect Your Warmup Emails

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:

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.

Understanding Warmup Health Scores

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 & Inbox Placement

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 Best Practices

Follow these best practices to get the most out of email warmup and build a strong sender reputation.

Do:

Do Not:

Timelines to Expect:

When to Adjust Settings:

Warmup & Campaigns: How They Work Together

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.

What to Do When Your Health Score Drops

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.

Multi-Domain Warmup Strategy

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:

Warmup Approach:

Campaign Distribution:

Monitoring:

Common Mistakes:

Warmup FAQ: Common Questions Answered

Frequently asked questions about email warmup.

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.

Understanding the Dashboard Health Score

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:

3) LinkedIn Sub-Score (20% weight, only if LinkedIn accounts exist) — Based on:

4) Campaign Sub-Score (10% weight) — Based on:

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.

Campaigns

Setting Up Your First Campaign

To create and launch your first email campaign:

  1. 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.
  1. Create Campaign — Go to Campaigns, click 'Create Campaign', and select 'Email Campaign' (you can also choose LinkedIn or Multichannel if you have LinkedIn seats).
  1. 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:

  1. 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.
  1. Review & Launch — Preview your emails with sample data, verify settings, and activate the campaign.
  1. 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%.

Campaign Types: Email, LinkedIn & Multichannel

WarmySender supports three campaign types:

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:

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.

Creating a Multichannel Campaign

Multichannel campaigns let you combine email and LinkedIn outreach in a single sequence for maximum engagement.

Getting Started:

  1. Go to Campaigns Hub and click 'New Campaign', then select 'Multichannel' as the campaign type.
  2. 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:

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.

Campaign Sequences & Follow-ups

Campaigns support multi-step sequences with automated follow-ups:

Step Configuration:

Delay Settings:

Stop Conditions:

Best Practices:

Merge Tags & Personalization

Merge tags let you personalize every email for each prospect automatically.

Built-in Tags:

LinkedIn-Specific Tags (in LinkedIn campaigns):

Sender Tags:

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:

Spintax — Dynamic Text Variations

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:

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:

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:

Preview & Testing:

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:

A/B Testing & Auto-Optimization

A/B testing lets you compare different email variants to find what works best.

How It Works:

  1. When creating a campaign step, add multiple variants — each with its own subject line and body content.
  2. Each variant gets a weight that determines what percentage of prospects receive it (e.g., 50/50 split for two variants).
  3. As emails are sent, the system tracks open rates, click rates, and reply rates for each variant independently.
  4. 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:

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 Windows & Schedules

Control when your campaign emails are sent:

Sending Window — Set the start and end hours for email delivery:

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:

How Scheduling Works:

  1. When a prospect is ready for their next step, the system calculates the scheduled send time (step delay + random jitter)
  2. If the scheduled time falls outside your sending window or on an inactive day, it automatically advances to the next valid time
  3. The system scans up to 8 days ahead to find the next valid slot
  4. Random jitter (1-5 minutes) is added between individual sends to avoid pattern detection

Best Practices:

Daily Sending Limits

WarmySender enforces multiple layers of sending limits to protect your deliverability:

Campaign-Level Limits:

Mailbox-Level Rate Limits:

Plan-Level Daily Limits:

Provider-Level Limits:

Domain-Level Limits:

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.

Campaign Safety & Cooldown

WarmySender automatically protects your sender reputation with safety features:

Bounce Rate Protection:

Spam Complaint Protection:

Reply Rate Floor (optional):

Cooldown & Recovery:

Mailbox Auth Protection:

Host Circuit Breaker:

Watchdog System:

Best Practices:

Mailbox Rotation

Assign multiple mailboxes to a single campaign and WarmySender will automatically rotate between them:

Rotation Modes:

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):

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.

Email Tracking (Opens, Clicks, Replies)

WarmySender tracks all key email engagement metrics:

Open Tracking:

Click Tracking:

Reply Tracking:

Bounce Detection:

Unsubscribe Handling:

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.

Images in Campaign Emails

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:

Deliverability Considerations:

Common Use Cases:

Note: WarmySender does not support file attachments (PDFs, documents, etc.) in campaign emails. See the 'Email Attachments in Campaigns' guide for alternatives.

Email Attachments in Campaigns

WarmySender does not support file attachments in campaign emails. This is an intentional design decision based on email deliverability best practices.

Why No Attachments:

Recommended Alternatives:

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.

Email Signatures per Mailbox

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:

Note: Signatures are not automatically appended — you must include {{signature}} in your email template body where you want the signature to appear.

Email Copywriting for Cold Outreach

Write cold emails that get opened, read, and replied to.

Subject Lines (Most Important):

Opening Line:

Body Structure:

Call to Action (CTA):

Follow-up Emails:

Common Mistakes:

Campaign Audience Segmentation

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:

By Industry:

By Company Size:

By Intent Signal:

Implementation in WarmySender:

  1. Create separate prospect lists per segment (e.g., 'SaaS CTOs', 'E-commerce VPs').
  2. Create separate campaigns per segment with tailored messaging.
  3. Use custom fields during CSV import to tag segments (custom:segment, custom:persona).
  4. Use merge tags to personalize within segments.

Best Practices:

Re-engagement Campaigns

Revive cold prospects who did not respond to your initial campaign.

When to Re-engage:

Re-engagement Strategy:

  1. Filter your prospect list to contacts who were 'contacted' but never 'replied'.
  2. Create a NEW campaign (do not re-enroll in the old one).
  3. Use a fresh angle — different subject line, different value proposition.
  4. Reference the previous outreach: 'I reached out a few weeks ago about...' (honesty works).
  5. 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:

Sending Pre-Written Personalized Emails (Everything as a Variable)

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:

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:

Common Mistakes to Avoid:

Managing Campaigns via API

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:

  1. Create a campaign (POST /api/v1/campaigns) — always created in draft status
  2. Review and adjust settings (PATCH /api/v1/campaigns/:id)
  3. Enroll prospects (POST /api/v1/campaigns/:id/enrollments) — accepts prospectIds, listIds, or emails
  4. Start the campaign (POST /api/v1/campaigns/:id/start)
  5. Monitor progress (GET /api/v1/campaigns/:id)
  6. Pause if needed (POST /api/v1/campaigns/:id/pause)
  7. 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:

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

Campaign API Error Handling

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:

Campaign Failed Prospects & Processing Errors

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.

  1. 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.
  1. Mailbox temporarily disconnected — If your mailbox has intermittent connection issues during the processing window.
  1. 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.

Campaign Overview Metrics (All-Time Totals)

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.

Send Pace Across Multiple Campaigns (Per-Mailbox Pacer)

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.

LinkedIn

LinkedIn Outreach Overview

WarmySender's LinkedIn add-on automates your LinkedIn outreach:

  1. 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.
  1. Purchase LinkedIn Seats — Go to Billing and purchase LinkedIn seats at $9/month per seat. Each seat allows one connected LinkedIn account.
  1. 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).
  1. 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:

  1. 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.
  1. Monitor Performance — Track acceptance rates, reply rates, and engagement from LinkedIn Analytics.
  1. 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.

LinkedIn Account Connection & Setup

Detailed guide for connecting your LinkedIn account:

Prerequisites:

Connection Steps:

  1. Go to LinkedIn > Accounts and click 'Connect Account'
  2. Choose your connection method — credentials, cookie-based, or OAuth
  3. Enter your LinkedIn login details
  4. If 2FA is enabled: you'll be prompted for a verification code. Enter it within 10 minutes.
  5. Wait for the connection to complete — your account will show 'Connected' status

Account Types Detected:

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.

LinkedIn Conversations & Messages

Manage all LinkedIn conversations from LinkedIn > Conversations:

Conversation List:

Message Thread:

Replying:

Campaign Integration:

The Unified Inbox also has a LinkedIn tab showing all LinkedIn conversations alongside your email replies for a complete view of all prospect interactions.

LinkedIn Safety Limits & Protection

WarmySender protects your LinkedIn account with multiple layers of safety:

Rate Limiting:

Account-Type Limits (weekly invites / daily messages hard cap):

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):

Safety Mechanisms:

Account Restriction Handling:

Why is my LinkedIn campaign sending slowly?

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.

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:

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

Reconnecting your LinkedIn account after a platform update

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.

Why does my LinkedIn account show as disconnected?

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:

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:

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.

Why is my LinkedIn account disconnected?

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

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:

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.

Why did my LinkedIn account disconnect — and how to reconnect

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:

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

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).

Understanding LinkedIn campaign acceptance rate

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

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

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.

LinkedIn Audiences & Enrichment

Audiences are collections of LinkedIn profiles used as targets for LinkedIn campaigns:

Creating Audiences:

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:

  1. The system processes profiles in small batches (up to 15 per tick, every 3 minutes) to mimic natural LinkedIn browsing.
  2. Each profile is fetched individually through your connected LinkedIn account — the same way you would view a profile manually on LinkedIn.
  3. A daily cap limits how many profiles can be enriched per day based on your account strategy (see below).
  4. When the daily cap is reached, enrichment pauses automatically and resumes at midnight UTC.
  5. 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.

LinkedIn Campaigns

Create and manage LinkedIn-only outreach campaigns from the LinkedIn section.

Creating a LinkedIn Campaign:

  1. Go to LinkedIn > Campaigns from the sidebar.
  2. Click 'Create Campaign' and give your campaign a name.
  3. Select the LinkedIn account to use for sending.
  4. Select an audience — choose one or more audiences as campaign targets.
  5. 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:

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:

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.

LinkedIn Posts & Engagement

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.

LinkedIn Likes API (Post Reactions)

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:

  1. Go to Settings > API Keys and create a new API key.
  2. Select the 'linkedin:read' and 'linkedin:write' scopes.
  3. Copy your API key (shown once — save it securely).
  4. Use the key in the Authorization header: Authorization: Bearer YOUR_API_KEY

Available Endpoints:

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: Purpose & Workflow

LinkedIn templates serve as reusable building blocks for your outreach campaigns. Here is how they work and why they matter:

What Templates Do:

Why You Edit Messages in Campaigns:

Template Types:

Workflow:

  1. Create templates in LinkedIn > Templates for your best-performing messages.
  2. When building a campaign step, click the template picker to select one.
  3. The template content fills the step editor — customize it for this specific campaign.
  4. Changes to the step do NOT modify the original template (they are independent after selection).
  5. 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.

Multi-Account LinkedIn Setup

WarmySender supports connecting multiple LinkedIn accounts within the same workspace, each requiring its own LinkedIn seat.

How Multi-Account Works:

Using Sales Navigator from a Different Account:

Sender Rotation:

Account Type Detection:

Premium Cookie Setup:

Best Practices:

LinkedIn Proxy & IP Security

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:

How It Works:

  1. When you connect a LinkedIn account, WarmySender assigns a dedicated fixed IP address to that account
  2. All LinkedIn requests for that account are routed through the assigned proxy — never directly from WarmySender servers
  3. The proxy IP is fixed (no rotation) and not shared with any other LinkedIn account
  4. 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:

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:

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.

LinkedIn Connection Request Notes

Connection request notes are the short personalized messages attached to LinkedIn connection invitations.

Blank vs. Personalized Notes:

Why You Might See Save Issues:

Best Practices for Invite Notes:

Example Invite Notes:

Note Character Counter:
The campaign step editor shows a live character counter (e.g., '147/300') to help you stay within LinkedIn's limit.

LinkedIn InMail Best Practices

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:

Writing Effective InMails:

Subject Line (Critical):

Message Body:

InMail in WarmySender Campaigns:

Best Practices:

Common Mistakes:

LinkedIn Profile Editing

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:

  1. Go to LinkedIn > Accounts
  2. Click on an account to open details
  3. Click 'Edit Profile' at the bottom of the dialog
  4. Update your headline, summary, or Open to Work status
  5. 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.

LinkedIn Message Management

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.

LinkedIn Analytics: Followers & Engagement

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:

  1. Resync Messages — Refreshes your messaging data from LinkedIn. Use this if messages appear out of sync or are missing. This is a lightweight operation.
  1. 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.

LinkedIn Recruiter Search Filters

Overview

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

  1. 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.
  1. 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.
  1. 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.
  1. 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.
  1. 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.
  1. 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.

LinkedIn Skill Endorsements (Beta)

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:

  1. Go to LinkedIn > Conversations or search for a prospect
  2. Click on the prospect's name to open their profile details
  3. Scroll to the 'Skills' section — you will see their listed LinkedIn skills
  4. Click the 'Endorse' button next to the skill you want to endorse
  5. The endorsement is submitted immediately and logged in the prospect's activity timeline

When to Use Standalone Endorsements:

—— BEST PRACTICES & GUIDELINES ——

—— RATE LIMITS & SAFETY ——

Endorsements share the daily engagement limit with post likes and comments. Here is the ramp-up schedule:

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:

Account Safety Notes:

—— 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.

LinkedIn Publishing & Reposts (Beta)

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:

  1. 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.
  1. 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.
  1. 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.
  1. 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.
  1. 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:

  1. Go to LinkedIn > Publishing in the sidebar
  2. Select your LinkedIn account from the dropdown
  3. Write your post content in the text area (maximum 3,000 characters)
  4. Choose visibility: Public (recommended for outreach) or Connections Only
  5. Optionally add an external link URL
  6. 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:

Visibility Options — When to Use Each:

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:

Repost Guide:

  1. Switch to the 'Repost' tab in the Publishing page
  2. Paste a LinkedIn post URL into the URL field
  3. The system automatically extracts the post URN (unique resource name) and displays it for confirmation
  4. Optionally add commentary — your own thoughts about the original post
  5. 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:

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:

Reading Engagement Metrics:

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:

Rate Limits & Account Safety:

WarmySender enforces conservative publishing limits to protect your LinkedIn account:

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.

LinkedIn Recruiting & Job Postings (Beta)

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:

Creating Job Postings — Detailed Guide:

  1. Navigate to LinkedIn > Recruiting in the sidebar
  2. Select the LinkedIn account you want to post from (each account posts independently)
  3. Click 'Create Job' to open the job creation form
  4. Fill in all required fields:
  1. 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:

Draft vs. Published States:

Publishing Jobs:

After creating a draft, click the 'Publish' button on the job card to make it live on LinkedIn.

Managing Applicants:

  1. Switch to the 'Applicants' tab on the Recruiting page
  2. Select a published job from the dropdown to view its applicants
  3. Use the sort options to organize your applicant list:

4) Each applicant card displays:

  1. 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:

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.

Closing Jobs:

Close a job posting when the position has been filled, the posting has expired, or you no longer want to receive applications.

Best Practices:

Rate Limits:

LinkedIn limits job posting activity to protect against spam and abuse:

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.

LinkedIn Proxy Management

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:

  1. Auto — WarmySender automatically assigns a proxy that matches your account's location. Best for most users.
  1. 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.
  1. 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:

  1. Go to LinkedIn > Accounts
  2. Click on an account to open details
  3. Click 'Change Proxy' next to the current proxy display
  4. Select your preferred mode and configure it
  5. 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.

Why my LinkedIn campaign sometimes sends outside my chosen hours (and how we fix it)

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:

  1. Open your campaign in the LinkedIn dashboard.
  2. 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').
  3. Look at the 'next scheduled send' indicator on the campaign card. It should always show a time inside your window.
  4. 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.

LinkedIn webhooks and Slack notifications: how replies and accepted invites flow to your team

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.

Example payload (`linkedin.reply_received`):

{
"event": "linkedin.reply_received",
"id": "evt_2026_04_28_aa11bb22cc33",
"occurredAt": "2026-04-28T09:34:18.512Z",
"workspaceId": "ws_abcdef0123456789",
"data": {
"campaignId": "camp_8c2f...",
"enrollmentId": "en_4a7b...",
"prospectId": "prs_4a7b...",
"prospectName": "Zoltan A. Vardy",
"prospectLinkedinUrl": "https://www.linkedin.com/in/zoltanvardy/",
"linkedinAccountId": "lia_9d11...",
"messageText": "Sounds good, send me the deck.",
"threadId": "thr_1f2e...",
"receivedAt": "2026-04-28T09:34:14.000Z"
}
}

Where to subscribe:

  1. Open Settings → Webhooks (`/settings?tab=webhooks`).
  2. 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.
  3. 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.
  4. Save. WarmySender returns a webhook secret — save it once (shown only on creation). Used for HMAC verification on your endpoint.
  5. 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.
  6. 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:

  1. 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).
  2. Check 'Recent Deliveries' on the same page — you'll see the response code and body within ~10 seconds.
  3. If 2xx: your endpoint accepted the test; you should see the message in Slack / Discord / your n8n flow.
  4. If 4xx: signature verification or formatting on your side rejected the payload; check the response body in Recent Deliveries for the error message.
  5. If 5xx: your endpoint had a server error; we'll retry up to 10 times with exponential backoff (1 min → 72 h).
  6. 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:

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.

How LinkedIn account safety limits work — invites, messages, InMails, and the gradual ramp

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:

  1. 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.
  1. Messages per day — How many direct messages to existing 1st-degree connections the account can send per day.
  1. 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.
  1. 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):

The four account types (and their ceilings):

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:

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:

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:

  1. Go to LinkedIn > Accounts in the sidebar.
  2. Click into a specific account.
  3. 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.
  4. 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):

| Account type | Invites/week | Messages/day | InMails/day | Profile views/day | Engagements/day |
|---|---|---|---|---|---|
| Free | 150 | 100 | 0 | 30 | 30 |
| Premium | 200 | 150 | 15 | 50 | 40 |
| Sales Navigator | 200 | 150 | 50 | 60 | 50 |
| Recruiter | 200 | 150 | 100 | 60 | 50 |

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 & Data

Managing Prospects & Contacts

Prospects are your campaign contacts, managed from the Prospects page:

Global Statuses:

Adding Prospects:

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:

Filtering & Search:

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.

Contacts & CRM

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:

Use the Contacts view to manage ongoing relationships and follow up with engaged prospects outside of automated campaign sequences.

Prospect Lists & Campaign Creation

Prospect Lists help you organize contacts and streamline campaign creation:

Creating Lists:

Using Lists for Campaigns:

List Management:

Import to Lists:
When importing via CSV, you can choose to add imported prospects to an existing list or create a new one during the import wizard.

Best Practices:

CSV Import (Advanced Guide)

Detailed guide for importing prospects via CSV:

Supported Columns:

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:

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:

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

Leads Database (B2B Contacts)

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:

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:

Accessing Leads:

Search Filters:

Lead Data Available:

Credits System:

Saving & Exporting:

Creating Campaigns from Leads:

  1. Save leads to a prospect list
  2. Go to the 'Saved Leads' tab
  3. Select your list and click 'Create Campaign from List'
  4. This navigates to the campaign wizard with the list pre-selected

Email Verifier

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.

Plan Limits:

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:

--- 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:

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:

Monthly Usage:

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:

Best Practices:

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.

Data Hygiene & List Cleaning

Clean data is the foundation of successful outreach. Poor data quality causes bounces, spam complaints, and reputation damage.

Why Data Hygiene Matters:

Before Importing (Pre-Import Cleaning):

  1. Remove obvious junk — blank rows, test entries, personal emails (gmail.com, yahoo.com for B2B campaigns).
  2. Standardize formatting — consistent name capitalization, remove extra spaces.
  3. Verify email format — every email must contain @ and a valid domain.
  4. Remove role-based emails — info@, sales@, support@, admin@ have high bounce and complaint rates.
  5. Check for suppressed domains — remove emails from domains on your blocklist.

Using WarmySender's Built-in Tools:

Ongoing Maintenance:

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:

Advanced Custom Fields Guide

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:

Popular Custom Field Ideas:

Segmentation with Custom Fields:

Limitations:

Best Practices:

Platform

Email & LinkedIn Templates

Templates save time by letting you reuse proven email and LinkedIn messages:

My Templates:

Template Categories (12):
Cold Outreach, Follow-up, Meeting Request, Introduction, Value Proposition, Case Study, Recruiting & HR, Partnership, Re-engagement, Agency Services, Other

Template Library (Pre-built):

Using Templates:

Best Practices:

Unified Inbox

The Unified Inbox aggregates all campaign replies across email and LinkedIn in one place:

Two Channels:

Filtering:

Thread View:

Replying:

Sentiment Tagging:

Bulk Operations:

Sync:

Thread Notes:
Add internal team notes to any thread — visible only to your workspace members, not sent to the prospect.

How We Measure Campaign Revenue (First-Touch Attribution)

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:

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:

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.

Analytics & Reporting

Track your outreach performance from the Analytics page:

Overview Dashboard:

Analytics Tabs:

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:

Teams & Workspaces

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:

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:

Team Member Limits by Plan:

Inviting Team Members:

  1. Go to Settings > Team tab
  2. Click 'Invite' (disabled when at plan limit — pending invites count toward limit)
  3. Enter the invitee's email address and select a role (Admin or User)
  4. They receive an email with a secure invitation link
  5. They click the link, log in (or create an account), and accept the invitation
  6. They're added to your workspace with the assigned role

Pending Invitations:

Workspace Switching:

Shared Resources:

Downgrading Plans & Workspaces:

Mailboxes vs. Team Members (Important Distinction):

Common Use Cases for Multiple Workspaces:

Billing & Subscription Plans

Manage your subscription from the Billing page:

Subscription Plans (monthly billing):

Annual Billing (save 40% — limited time):

How the limited-time 40% annual offer works:

All Paid Plans Include:

LinkedIn Seats (Add-On):

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:

Billing Management:

Subscription Statuses:

When your subscription becomes inactive, active campaigns are automatically paused. They auto-resume when you re-subscribe.

Suppression Lists & Compliance

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:

Enforcement:

CAN-SPAM Compliance:

GDPR Compliance:

Best Practice: Regularly review and clean your suppression list. Add competitor domains, existing customer domains, and known bad addresses proactively.

Email Deliverability (SPF, DKIM, DMARC)

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):

DKIM (DomainKeys Identified Mail):

DMARC (Domain-based Message Authentication, Reporting & Conformance):

Verification:

Common DNS Providers:

Impact: Domains with all three records properly configured see significantly higher inbox placement rates (80%+ vs. 40-60% without).

Custom Tracking Domains

Set up a custom tracking domain for better email deliverability:

Why Custom Tracking Domains:

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:

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).

Bounce Shield Protection

Bounce Shield is WarmySender's configurable bounce protection system:

Settings (from Settings > Bounce Shield):

How It Works:

  1. WarmySender monitors bounce rates across your recent sends
  2. When the bounce rate within the configured window exceeds your threshold, Bounce Shield activates
  3. If auto-pause is enabled, affected campaigns are paused to prevent further damage
  4. If auto-blocklist is enabled, bounced addresses are added to your suppression list
  5. 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.

API Keys & Webhooks

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:

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:

For full API reference, visit warmysender.com/docs/integrations

Onboarding & Product Tours

WarmySender includes guided tours to help you get started:

Main Onboarding Tour:

Page-Specific 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.

Security & Compliance

WarmySender takes security seriously. Here is an overview of our security practices:

Data Encryption:

Authentication & Access:

Infrastructure:

Email Security:

Compliance:

Data Retention:

Security Page:
For our full security policy, visit warmysender.com/security.
Privacy Policy: warmysender.com/privacy.

For security inquiries, contact us at hello@warmysender.com.

Webhook Integration Guide

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):

  1. Go to Settings > Webhooks.
  2. Click 'Create Webhook'.
  3. Enter your endpoint URL (where WarmySender sends the event data).
  4. Select which events to subscribe to.
  5. Copy the webhook secret for signature verification.
  6. Click 'Test' to send a test event and verify your endpoint.

Available Events:

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:

Integration Examples:

CRM Sync (HubSpot, Salesforce, Pipedrive):

Slack/Teams Notifications:

Zapier / Make / n8n:

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.

API Quickstart Tutorial

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:

Full API Reference:
Visit warmysender.com/docs/integrations for complete endpoint documentation with request/response examples, error codes, and webhook setup.

Best Practices:

Webhook Events Reference

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.

Payload Format (all events):
{
"type": "email.clicked",
"data": { ...event-specific fields... },
"timestamp": "2026-03-20T14:30:00.000Z"
}

Headers Included:

Subscribing to Events:

Webhook Signature Verification

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:

  1. When you create a webhook, you receive a secret (format: whsec_xxxx). Save it securely.
  2. Every webhook delivery includes an X-Warmy-Signature header.
  3. The header format is: t=<timestamp>,v1=<hex_signature>
  4. To verify, reconstruct the signature using your secret and compare.

Verification Steps:

Step 1: Extract timestamp and signature from X-Warmy-Signature header:

Step 2: Build the signature payload:

Step 3: Compute HMAC-SHA256:

Step 4: Compare signatures:

Step 5 (Optional): Check timestamp freshness:

Node.js Example:
const crypto = require('crypto');

function verify(secret, signatureHeader, body) {
const [tPart, vPart] = signatureHeader.split(',');
const timestamp = tPart.replace('t=', '');
const signature = vPart.replace('v1=', '');
const payload = timestamp + '.' + body;
const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature, 'hex'), Buffer.from(expected, 'hex'));
}

Python Example:
import hmac, hashlib

def verify(secret, signature_header, body):
parts = dict(p.split('=', 1) for p in signature_header.split(','))
payload = parts['t'] + '.' + body
expected = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(parts['v1'], expected)

Common Mistakes:

Domain Reputation Monitoring

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:

External Monitoring Tools (Recommended):

Reputation Factors:

Improving Reputation:

  1. Verify email lists before sending (use Email Verifier).
  2. Warm up properly — do not skip the 2-3 week warmup period.
  3. Start campaigns with low volume (20-30/day) and increase gradually.
  4. Monitor bounce rates and stop campaigns immediately if above 5%.
  5. Keep warmup running in Maintenance mode alongside campaigns.
  6. Remove non-engaging prospects after 3-4 touchpoints.
  7. 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.

Integrations

Webhooks — Getting Started

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:

All events use the same envelope: { type, data, timestamp }.

Creating a Webhook:

  1. Settings → Webhooks → New webhook.
  2. 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.
  3. Pick events. Start with reply.received + linkedin.reply_received + linkedin.invite_accepted for sales teams; add email.bounced + limit.hit for ops.
  4. Save. WarmySender returns a webhook secret — save it somewhere secure, you'll need it to verify signatures. The secret is shown once.
  5. 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:

Troubleshooting:

Related Guides: 'Slack Notifications' (native, no middleware), 'n8n Integration', 'Zapier Integration', 'Make Integration', 'HubSpot CRM Integration'.

HubSpot CRM Integration

Connect WarmySender to HubSpot CRM to automatically sync prospect activity and campaign data.

What This Integration Does:

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:

Best Practices:

Salesforce Integration

Connect WarmySender to Salesforce to sync campaign activity and create leads automatically.

What This Integration Does:

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:

Best Practices:

Pipedrive Integration

Connect WarmySender to Pipedrive to sync prospect activity and manage your sales pipeline.

What This Integration Does:

Setup Option 1: Direct Webhook

Step 1: Create a handler endpoint
Build a server or serverless function that receives WarmySender webhook events.

Step 2: Configure in WarmySender
• Settings > Webhooks > Create Webhook.
• Enter your endpoint URL.
• Subscribe to: reply.received, email.opened, email.clicked, email.bounced.

Step 3: Map events to Pipedrive
• reply.received → Search Person by email, create if not found, create Deal in first pipeline stage, add Activity (type: 'email', subject: 'Prospect replied')
• email.opened → Add Activity (type: 'email', subject: 'Email opened')
• email.clicked → Add Activity, move Deal to 'Interested' stage
• email.bounced → Update Person, mark Deal as Lost (reason: 'Invalid email')

Pipedrive API Basics:

Setup Option 2: Via Zapier
Use Zapier Webhooks (Catch Hook) trigger + Pipedrive actions. No code required.

Best Practices:

Zapier Integration

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:

  1. Reply received → Create HubSpot deal + Notify Slack channel
  2. Email bounced → Update Google Sheet row + Remove from Mailchimp list
  3. Link clicked → Create Pipedrive activity + Send Slack DM to sales rep
  4. Prospect suppressed → Update Airtable record

Tips:

Make (Integromat) Integration

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:

Best Practices:

n8n Integration (Self-Hosted)

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:

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:

  1. On the Webhook trigger node, under 'Options', enable 'Raw Body' so the raw bytes are preserved on `$binary.data`.
  2. 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.

LinkedIn Event Payload Shape:
linkedin.reply_received:
data: { prospectId, prospectName, prospectLinkedinUrl, campaignId, enrollmentId, linkedinAccountId, messageText, threadId, receivedAt }
linkedin.invite_accepted:
data: { prospectId, prospectName, prospectLinkedinUrl, campaignId, enrollmentId, linkedinAccountId, acceptedAt }

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:

Best Practices:

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.

Slack Notifications (Native — No Middleware)

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:

Setup (5 minutes, no code):

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:

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:

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.

Reliability:

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.

Google Sheets Integration

Automatically log WarmySender campaign events to Google Sheets for reporting and analysis.

What This Integration Does:

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:

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:

Best Practices:

GoHighLevel (GHL) Integration

Connect WarmySender to GoHighLevel (GHL) for agency CRM sync and lead management.

What This Integration Does:

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:

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):

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):

Best Practices:

Airtable Integration

Connect WarmySender to Airtable to build a custom engagement tracking database.

What This Integration Does:

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:

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:

Best Practices:

MCP Server — Connect AI Tools (Overview)

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:

What You Cannot Do (by design):

Supported AI Clients:

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):

Rate Limits (per workspace, per minute):

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.

Full dedicated reference: warmysender.com/mcp

MCP Server — Install in Claude Desktop / Claude Code / Cursor / Windsurf / Zed

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:

  1. Go to Settings > API Keys > Create API Key.
  2. Name it (e.g., "Claude Desktop" so you can revoke per-client later).
  3. 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.
  4. 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):

{
"mcpServers": {
"warmysender": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://warmysender.com/mcp",
"--header",
"Authorization: Bearer ws_YOUR_API_KEY_HERE"
]
}
}
}

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:

claude mcp add warmysender --transport http https://warmysender.com/mcp --header "Authorization: Bearer ws_YOUR_API_KEY_HERE"

Verify with: claude mcp list — you should see warmysender. Restart any active claude session to pick up the change.

Cursor:
Open your project's .cursor/mcp.json (or ~/.cursor/mcp.json for global) and paste:

{
"mcpServers": {
"warmysender": {
"url": "https://warmysender.com/mcp",
"headers": {
"Authorization": "Bearer ws_YOUR_API_KEY_HERE"
}
}
}
}

Restart Cursor. Open the Cursor Settings > MCP tab to confirm warmysender is listed and connected.

Windsurf (Codeium):
Edit ~/.codeium/windsurf/mcp_config.json:

{
"mcpServers": {
"warmysender": {
"serverUrl": "https://warmysender.com/mcp",
"headers": {
"Authorization": "Bearer ws_YOUR_API_KEY_HERE"
}
}
}
}

Restart Windsurf.

Zed:
Zed uses stdio so we bridge with mcp-remote. Open Zed settings (Cmd+,) and merge into your settings.json:

{
"context_servers": {
"warmysender": {
"command": {
"path": "npx",
"args": [
"-y",
"mcp-remote",
"https://warmysender.com/mcp",
"--header",
"Authorization: Bearer ws_YOUR_API_KEY_HERE"
]
}
}
}
}

Restart Zed.

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.

Manual curl Test (from your terminal):

curl -X POST https://warmysender.com/mcp \
-H "Authorization: Bearer ws_YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'

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:

See also: "MCP Server — Available Tools Reference" and "MCP Server — Safety, Scopes, and Rate Limits."

MCP Server — Available Tools Reference (30 tools)

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:

Mailboxes & Warmup:

LinkedIn:

Other:

EMAIL WRITES — 11 tools (all idempotent with optional idempotency_key):

Prospects:

Campaigns:

Enrollments & Suppressions:

LINKEDIN + WARMUP WRITES — 5 tools (stricter rate limits, safety-gated):

META — 1 tool:

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

MCP Server — Safety, Scopes, and Rate Limits

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:

Revoking takes effect immediately — Settings > API Keys > Delete. The AI client's next call gets 401.

RATE LIMITS (per workspace, sliding 60-second window):

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:

DATA THE AI NEVER SEES:

RED-TEAM TESTS WE RAN:

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."

Troubleshooting

"534-5.7.14 Invalid login" error

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.

"Connection refused" error

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.

"SMTP authentication disabled" or error 5.7.139

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:

How to fix (requires your IT admin):

For Microsoft 365:

  1. Your admin must go to Microsoft 365 Admin Center (admin.microsoft.com).
  2. Navigate to Users → Active Users → Select your account.
  3. Click the Mail tab → Manage email apps.
  4. Check the box for 'Authenticated SMTP' and save.
  5. Wait 15-30 minutes for the change to propagate.

If your organization has Security Defaults enabled (common for new M365 tenants):

  1. Your admin must go to Azure Portal (portal.azure.com) → Microsoft Entra ID → Properties.
  2. Click 'Manage Security Defaults' at the bottom.
  3. Set 'Security defaults' to Disabled (note: this reduces security for the entire org — discuss with your IT team).
  4. 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.

"Server not found" or DNS resolution error

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:

  1. Typo in the hostname — Double-check for misspellings (e.g., 'smpt.gmail.com' instead of 'smtp.gmail.com').
  2. 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).
  3. Domain expired or DNS not configured — If using a custom domain, verify it has not expired and has valid MX records.
  4. Temporary DNS issue — Try again in a few minutes. If persistent, try using a different network or contact your internet provider.

Correct hostnames for common providers:

Debugging: Copy-paste the hostname from the Provider Setup Guides above to avoid typos.

"Authentication failed" error

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:

Provider-Specific Steps:

Gmail:

  1. You must use an App Password, not your regular Google password.
  2. Go to https://myaccount.google.com/apppasswords (2FA must be enabled first).
  3. Generate a new App Password for 'Mail' and paste it into WarmySender.
  4. Your username must be your full Gmail address (e.g., you@gmail.com).

Outlook / Microsoft 365:

  1. Generate an App Password at https://account.live.com/proofs/AppPassword or via your M365 admin portal.
  2. 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'.
  3. Your username must be your full email address (e.g., you@outlook.com or you@yourdomain.com).
  4. 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:

  1. Use your regular email password (not an App Password).
  2. SMTP host must be smtp.hostinger.com (not mail.yourdomain.com).
  3. Your username is your full email address (e.g., you@yourdomain.com).
  4. If you recently changed your password, wait a few minutes for propagation.

Zoho:

  1. If 2FA is enabled, generate an App Password at https://accounts.zoho.com/home#security/security_apppassword.
  2. If 2FA is not enabled, your regular Zoho password should work.
  3. Your username is your full email address.
  4. SMTP host: smtp.zoho.com (or smtp.zoho.eu / smtp.zoho.in depending on your region).

Yahoo:

  1. You must use an App Password. Go to https://login.yahoo.com/account/security and generate one under 'App Passwords'.
  2. Your username is your full Yahoo email address.

Debugging Steps:

  1. Verify your username is your full email address (e.g., user@domain.com), not just the part before the @.
  2. Re-generate a fresh App Password and paste it carefully — avoid trailing spaces.
  3. Confirm the SMTP host and port match your provider's requirements (see Provider Setup Guides).
  4. Log in to your email provider's web interface and check for any security alerts or prompts that need to be resolved.
  5. If you recently enabled 2FA, any previously saved passwords are invalidated — generate a new App Password.
  6. 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.

"Self-signed certificate" or SSL/TLS errors

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):

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.

"Mailbox not found" error

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:

  1. 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.
  2. Typo in email address — Double-check for misspellings, extra spaces, or wrong domain (e.g., @gmial.com instead of @gmail.com).
  3. 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.
  4. 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:

Debugging Steps:

  1. Copy-paste your email address to avoid typos.
  2. Log in to your email provider's webmail to confirm the account is active and accessible.
  3. Check with your domain administrator that the mailbox has not been deleted or disabled.
  4. If using a custom domain, verify that MX records are properly configured and pointing to the correct mail server.

Warmup emails going to spam

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.

Warmup not sending emails or volume is very low

If your warmup is enabled but you see very few or no emails being sent, check these common causes:

  1. Mailbox Connection — Go to your mailbox and verify the status shows 'Connected'. If it shows an error or 'Disconnected', reconnect the mailbox.
  1. Warmup Toggle — Make sure warmup is actually enabled for the mailbox (the toggle should be on).
  1. 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.
  1. Subscription Status — Warmup requires an active paid subscription. If your subscription expired or was cancelled, warmup is automatically paused.
  1. 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.
  1. 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.
  1. 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.

Campaign not sending

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.

"Too many requests" or rate limiting

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.

Mailbox disconnected or connection lost

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.

Daily sending limit reached

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.

LinkedIn account restricted or blocked

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.

LinkedIn invites not being accepted

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.

Campaign in cooldown mode

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.

CSV import failed or contacts not imported

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.

Tracking domain verification failed

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.

Emails landing in Promotions or spam folder

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.

How unsubscribe links work

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:

When a prospect clicks unsubscribe:

Viewing unsubscribed contacts:

Compliance:

Google or Outlook OAuth token expired

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.

LinkedIn analytics showing fewer connections than expected

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:

  1. 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.
  1. Manual acceptances — If you sent connection requests outside of WarmySender (directly on LinkedIn), those are not tracked in campaign analytics.
  1. 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.
  1. 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.
  1. 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.

To get the most accurate picture:

Excel (.xlsx) file import not working

WarmySender only supports CSV (Comma-Separated Values) file format for prospect imports. Excel files (.xlsx, .xls) are not directly supported.

How to Convert Your File:

From Microsoft Excel:

  1. Open your Excel file.
  2. Click File > Save As (or Export).
  3. In the 'Save as type' dropdown, select 'CSV (Comma delimited) (*.csv)' or 'CSV UTF-8 (Comma delimited) (*.csv)'.
  4. Click Save. If prompted about losing features, click 'Yes' — CSV only stores data, not formatting.
  5. Upload the resulting .csv file to WarmySender.

From Google Sheets:

  1. Open your spreadsheet in Google Sheets.
  2. Click File > Download > Comma Separated Values (.csv).
  3. The CSV file downloads to your computer.
  4. Upload this .csv file to WarmySender.

From Apple Numbers:

  1. Open your file in Numbers.
  2. Click File > Export To > CSV.
  3. Click Save.
  4. Upload the .csv file to WarmySender.

CSV Requirements:

Common Issues After Conversion:

Tip: After converting, open the CSV in a text editor (Notepad, TextEdit) to verify it looks correct before uploading.

Campaign paused or not running within sending window

If your campaign appears paused or is not sending emails even though it is within the active sending window, check these common causes:

  1. 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.
  1. Campaign status — Make sure the campaign status is 'Running' (not 'Draft', 'Paused', 'Cooldown', or 'Completed'). Check the Campaigns page for the status badge.
  1. 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.
  1. 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.
  1. 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.
  1. 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.
  1. 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.
  1. No eligible prospects — All enrolled prospects may have already been contacted, replied, bounced, or unsubscribed. Check the campaign's prospect enrollment status.
  1. Campaign end date passed — If you set an end date and it has passed, the campaign stops automatically.
  1. 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:

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.

Cannot save LinkedIn connection step with blank message

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:

  1. 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.
  1. 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.
  1. Template selection issue — If you selected a template but then cleared the text, try deselecting the template entirely (set template to 'None') before saving.
  1. Browser cache — Try refreshing the page (Ctrl+F5 / Cmd+Shift+R) and re-entering the step configuration.
  1. 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:

DNS record setup not working (SPF, DKIM, DMARC)

Step-by-step troubleshooting for DNS authentication records:

  1. Propagation delay — DNS changes can take 24-48 hours to take effect globally. If you just added records, wait and re-check.

2) SPF record issues:

3) DKIM record issues:

4) DMARC record issues:

5) Verification in WarmySender:

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.

Slow warmup progress or low daily volume

If your warmup volume seems stuck or is ramping up too slowly:

  1. 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.

  1. 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.
  1. 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.
  1. Shared quota — If you are running campaigns, warmup and campaigns share the daily sending limit. Campaign sends reduce available warmup capacity.
  1. Peer availability — During off-peak hours or with a small warmup pool, fewer peers may be available. This is temporary and self-correcting.
  1. Connection issues — Verify your mailbox shows 'Connected' status. A disconnected mailbox cannot send or receive warmup emails.
  1. 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.

Handling spam complaints from recipients

If recipients are marking your campaign emails as spam, take immediate action:

  1. 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.
  1. 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:

4) Root causes and fixes:

5) Recovery:

Account login issues or session expired

Common login and session issues:

  1. Session expired — Sessions last 30 days by default. After expiry, you need to log in again. This is normal security behavior.
  1. 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:

  1. 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.
  1. Account disabled — If your subscription expired or was deactivated, you can still log in but access is limited to the Billing page for reactivation.
  1. 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:

If none of these resolve your issue, contact support at hello@warmysender.com with your account email for assistance.

Webhook events not firing or not received

If your webhook endpoint is not receiving events from WarmySender:

  1. 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:

  1. Test your endpoint — Click 'Test' in webhook settings to send a test event. If the test fails, your endpoint has an issue.
  1. 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:

  1. Retry policy — Failed deliveries are retried up to 10 times with exponential backoff (1min to 72hrs). Events are not lost on first failure.
  1. Signature verification — Verify using the X-Warmy-Signature header with your webhook secret (HMAC-SHA256). Format: t=timestamp,v1=signature.
  1. 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.

LinkedIn Search Errors or Missing Filters

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 taking too long (days or weeks)

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:

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.

LinkedIn enrichment failed or stopped

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:

  1. Reconnect your LinkedIn account if disconnected
  2. Go to LinkedIn > Audiences and select your audience
  3. Click 'Start Enrichment' or 'Retry' to restart the process
  4. Previously enriched profiles are cached — the system picks up where it left off, not from scratch

Why does enrichment use my LinkedIn account?

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:

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.

Can I start a LinkedIn campaign without enrichment?

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:

Recommended Workflow for Large Audiences:

  1. Import your audience (e.g., 1,000 profiles from a Sales Navigator search)
  2. Start enrichment in the background (LinkedIn > Audiences > Start Enrichment)
  3. Create your campaign immediately — do not wait for enrichment
  4. Launch the campaign — it will process prospects using available data
  5. 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.

Dashboard health score dropping but warmup scores are fine

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:

  1. 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.
  1. 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.
  1. 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.
  1. 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:

Analytics page showing no data or not updating

If your Analytics page shows no data or appears empty, check the following:

  1. 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).
  1. 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.
  1. 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.
  1. 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.
  1. 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.
  1. 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.
  1. Browser cache — Try a hard refresh (Ctrl+F5 or Cmd+Shift+R) to force reload the page data.
  1. 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.

Prospects failed with 'stuck in processing loop' error

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:

  1. 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.
  1. 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.
  1. 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:

  1. Add more mailboxes to your campaign — Go to Campaign Settings and assign 3-5 mailboxes. Use mailbox rotation (round-robin) to distribute load.
  1. Reduce daily campaign volume — Lower your per-campaign daily send limit to match your available mailbox capacity.
  1. 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.
  1. 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.

Why prospects might fail and how to fix

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:

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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.

LinkedIn endorsement step skipping — no endorsable skills found

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:

  1. The prospect has not listed any skills on their profile
  2. The prospect's skills don't have endorsement IDs (rare technical issue)
  3. 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.

Cannot delete LinkedIn message — 60 minute window expired

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:

  1. Send a follow-up correction message
  2. 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.

Can I use LinkedIn without a paid subscription?

No — the LinkedIn add-on requires an active paid subscription (any paid plan). Free-tier users cannot purchase or use LinkedIn seats.

To get started with LinkedIn:

  1. Upgrade to a paid plan from the Billing page
  2. Purchase LinkedIn seats ($9/month per seat)
  3. Connect your LinkedIn account

If you're on a free plan, you'll see a locked LinkedIn card on the Billing page with an option to upgrade.

What happens to LinkedIn if I cancel my main subscription?

If your main subscription is canceled or becomes inactive, your LinkedIn add-on is also affected:

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.

How do I cancel just the LinkedIn add-on?

To cancel only your LinkedIn add-on (without affecting your email plan):

  1. Go to the Billing page
  2. Scroll to the LinkedIn Prospecting Add-On section
  3. Click 'Cancel Add-On'
  4. Confirm the cancellation

What happens when you cancel:

You can reactivate LinkedIn at any time from the Billing page. Reactivation restores your previous seat count and billing resumes immediately.

How do I create additional workspaces?

Your first workspace is created automatically when you sign up. To create additional workspaces (available on Business and Enterprise plans):

  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 and click Create

Workspace limits by plan:

Key details:

Pro plan users: Upgrade to Business ($29.99/month) from the Billing page to unlock multiple workspaces.

How does billing work with multiple workspaces?

Your subscription plan covers your entire account, including all workspaces you own:

Workspace limits by plan:

Example — Agency on Business ($29.99/month) with 3 workspaces:

Why does my Open Rate or Click Rate exceed 100%?

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.

How are Out of Office replies handled?

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:

  1. Open the Unified Inbox and click the reply in question
  2. Change the sentiment to 'Out of Office'
  3. 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.

How many mailboxes can I connect and warm up?

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:

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).

What does 'team members' or '2 members' mean?

Team members refers to the number of people who can access your WarmySender workspace. Each member gets their own login account.

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:

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.

Can I manage multiple domains and mailboxes in one workspace?

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:

Key points:

When to use multiple workspaces instead:

My free trial expired — what happens now?

When your 7-day free trial expires without subscribing, your account is downgraded to a restricted state:

To re-activate your account:

  1. Log in to WarmySender
  2. You'll see the Billing page with available plans
  3. Subscribe to Pro ($14.99/mo), Business ($29.99/mo), or Enterprise ($69.99/mo)
  4. Your account is immediately unlocked
  5. Resume your paused campaigns and warmup

Your data is safe — subscribing restores full access to everything you set up during the trial.

How do I upgrade or downgrade my plan?

You can change your plan at any time from the Billing page.

To change your plan:

  1. Go to the Billing page (click your profile > Billing, or navigate to /billing)
  2. Click 'Change Plan'
  3. Select your new plan
  4. If you have a promo code, enter it to see the discounted price
  5. Confirm the change

Upgrading:

Downgrading:

If you are on a free trial (no credit card on file), changing plans will take you through a full checkout process.

I exceeded my monthly email limit — what happens?

When you reach your monthly email quota, campaign sending pauses automatically until your quota resets at the start of your next billing cycle.

Monthly quotas by plan:

What happens:

Options to resolve:

  1. Wait for your next billing cycle — your quota resets automatically when your subscription renews
  2. Upgrade your plan — higher plans take effect immediately with the new quota
  3. Add more mailboxes and stagger campaigns across billing cycles to stay within limits

To check your current usage, visit the Billing page. Daily limits also apply: Pro ≈ 333/day, Business ≈ 3,333/day, Enterprise ≈ 10,000/day.

How does LinkedIn add-on billing work?

The LinkedIn add-on is a separate subscription billed at $9/seat/month, available on any paid plan.

Key details:

Adding LinkedIn seats:

  1. Go to the Billing page
  2. Click 'Add LinkedIn Seats' (or manage existing seats)
  3. Choose how many seats you need
  4. Payment is processed via Stripe

Canceling LinkedIn seats:

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.

How do I apply a promo or discount code?

You can apply a promo code when subscribing or when changing your plan.

During initial checkout:

When changing plans (existing subscribers):

  1. Go to the Billing page
  2. Click 'Change Plan'
  3. Select your new plan
  4. Enter your promo code in the promo code field
  5. 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.

Can I get a refund?

For refund requests, please review our Refund Policy at warmysender.com/refund-policy.

General guidelines:

To avoid unwanted charges:

What payment methods are accepted? Where are my invoices?

Payment Methods:

Invoices & Billing History:

Updating Your Payment Method:

  1. Go to the Billing page
  2. Click 'Manage Subscription' or 'Update Payment Method'
  3. Enter your new card details in the secure Stripe form
  4. Your next charge will use the updated card

Do you offer annual or yearly pricing?

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):

Monthly Pricing:

How the limited-time 40% annual offer works:

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.

How do I change my mailbox's daily sending limit?

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.

Why does my LinkedIn campaign say 'paused' with no reason?

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:

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.

I imported Sales Navigator URLs but most of my prospects didn't get invites — what happened?

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:

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.

I see my invite counter went up but the dashboard says 0 invites — is the counter wrong?

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.

I see prospects who replied on LinkedIn but my dashboard says 0 replies — what's wrong?

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:

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.

Many of my prospects say 'Profile inaccessible' — are they lost?

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:

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:

What you should do:

No manual un-burn is needed for the 21,868 historical cohort — the backfill handled it automatically.

I imported a CSV with custom fields but my template variables show 'undefined' — what should I do?

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:

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:

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.

My LinkedIn replies aren't showing on the dashboard — what's happening?

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:

What WarmySender does during the outage:

  1. The 15-minute webhook health monitor fires a critical-severity admin alert within one tick of the outage starting.
  2. 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.
  3. 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:

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.

Why are some of my prospects shown as accepted but never received a follow-up message?

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:

  1. 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.
  2. 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.
  3. 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.

Why are my campaign stats showing zero accepts when I have replies?

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:

If you still see the issue:

No Unipile API calls are involved in the counter — every fix is a DB-state hygiene fix on signals we already received.

I see a 'Template syntax invalid' error — what do I do?

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:

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.

Why is my account counter different from what the campaign shows?

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:

How to verify the messages actually went out:

  1. Open the campaign card and check the per-step activity counter — it shows ground-truth from campaign_events.
  2. Open the LinkedIn inbox for the account and confirm the messages are visible in your sent items.
  3. 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

How to verify in the UI

  1. Open the campaign and check the status pill. running means active; paused shows a reason.
  2. 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.
  3. On the LinkedIn account card, check ramp week (1-4) and remaining daily / weekly headroom.
  4. Open the Activity tab on a prospect for the full audit trail of attempts and errors.

How LinkedIn webhooks work end-to-end

Configuration

  1. Settings › Webhooks › New Webhook. Paste your endpoint URL (Slack Incoming Webhook, Zapier Catch Hook, n8n / Make HTTP Trigger, or your own HTTPS endpoint).
  2. Pick the events: linkedin.invite_accepted, linkedin.message_sent, linkedin.reply_received, linkedin.account_disconnected. Subscribe to * for everything.
  3. Click Test webhook — WarmySender fires a sample linkedin.invite_accepted payload to your URL.

Sample payload (linkedin.invite_accepted)

{
  "event": "linkedin.invite_accepted",
  "id": "evt_2026_04_27_aa11bb22cc33",
  "occurredAt": "2026-04-27T11:32:14.512Z",
  "workspaceId": "ws_abcdef0123456789",
  "data": {
    "campaignId": "camp_8c2f...",
    "prospectId": "prs_4a7b...",
    "linkedinAccountId": "lia_9d11...",
    "invitedAt": "2026-04-17T13:57:01.000Z",
    "acceptedAt": "2026-04-27T11:32:14.000Z"
  }
}

Sample payload (linkedin.reply_received)

{
  "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 typeInMails / dayConnection invites / weekNotes
Free0 (no InMail credits)100 / week capped by rampCold messaging only via accepted connections.
Premium25100 / week capped by rampDefault conservative paid tier.
Sales Navigator50100 / week capped by rampBest for cold outreach to non-connections.
Recruiter / Recruiter Lite50100 / week capped by rampRecruiter-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.

4-week safety ramp

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

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.

Need More Help?

Contact us at hello@warmysender.com — we respond within 24 hours on business days.

Visit our Email Warmup FAQ, Deliverability FAQ, or LinkedIn Safety FAQ for more answers.

For API integration, see our API Documentation.