Documentation & Help Center

Set up warmup, launch cold email campaigns, and run LinkedIn and Instagram outreach — with safe sending limits and inbox placement built in.

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

Browse documentation by topic

Each guide below opens on its own page.

Getting Started

Email Warmup

Campaigns

LinkedIn

Instagram

Platform

WhatsApp

Prospects & Data

Integrations

SEO & Content

SEO

Performance

Billing & Plans

Warmup

AI Agents

Troubleshooting

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",
    "lateAccept": false,
    "lateAcceptObservedAt": null
  }
}

lateAccept is true when the person accepted after their last step in the campaign had already run, and false for a normal accept; lateAcceptObservedAt is the time we noticed a late accept (or null). The event fires once per person per campaign, including for late accepts, and nothing extra is sent on LinkedIn because of it.

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 in the form t=<milliseconds>,v1=<hex>. v1 is the HMAC-SHA256 of timestamp + "." + raw body, using the signing secret shown once when you create the webhook or when an owner or admin clicks Rotate secret. Compare with a constant-time check:

const payload = timestamp + "." + body;
const expected = crypto.createHmac("sha256", secret).update(payload).digest("hex");
const header = "t=" + timestamp + ",v1=" + expected;

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

A delivery your address does not accept is tried again, up to 10 times. The wait before each retry grows: 5 minutes, 15 minutes, 1 hour, 3 hours, 6 hours, 12 hours, 1 day, 2 days, then 3 days. A test send is a signed webhook.test event and uses that same schedule. After 50 events in a row each use up all 10 tries, the webhook is paused. An owner or admin clicks Turn back on to start the count over.

How is InMail delivery verified?

Every LinkedIn InMail send goes through a strict delivery-proof gate before WarmySender will count it as a successful send. The gate works at the platform-contract level: the LinkedIn integration returns a conversation identifier when a real InMail lands on LinkedIn's side. WarmySender treats that identifier as the proof-of-delivery fingerprint: if it's missing, the send is treated as a silent drop, the dashboard counter does not increment, the daily InMail cap is not consumed, and the prospect's last-messaged timestamp is left untouched.

What changes for you

What you'll see in your activity history

Every send is recorded with a structured entry your support team can reference:

[InMail] account=... recipient=... conversation=... deliveryProven=true

On a failure, the same entry appears with deliveryProven=false and a reason such as eligibility, rate limit, or missing confirmation, plus the underlying detail from LinkedIn. Customer support uses these records to confirm whether a "missing send" was a phantom drop (now blocked) or a genuine eligibility skip (recipient closed their account, etc.).

Backfill of historical phantom sends

Pre-fix the platform was misclassifying every InMail failure as a successful send. The historical phantom rows are being annotated as phantom rather than deleted — preserving the audit trail while excluding them from "sent" counts going forward. Your dashboard counts will go down briefly when this annotation runs; that drop reflects the truth, not a bug.

Why we don't make extra verification calls

WarmySender's account-safety contract is "every LinkedIn API call is a potential rate-limit hit, every rate-limit hit is a potential restriction." We do not make a follow-up call to "confirm" each send — instead, we rely on the conversation identifier returned by the original send call. This keeps the per-account API budget exactly the same as before the fix, while delivering 100% accuracy on the delivery counter.

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 LinkedIn restricts an account, we automatically put it back on the gentlest pace and start the easing-in again from week one, so the account rebuilds safely from scratch.

What happens when InMail credits run out

When your Sales Navigator (or Premium / Recruiter) account uses its last InMail credit and LinkedIn reports "not enough credits", WarmySender stamps an account-level credits-exhausted flag. For the next 24 hours every InMail step on that account is skipped — the prospect advances to the next step in your sequence (or completes the sequence if InMail was the last step) instead of holding a slot in the campaign’s daily send budget. After 24 hours WarmySender re-tries one InMail; if your credits have been topped up the flag clears automatically and normal sending resumes. This protects your daily send budget so connection invites and follow-up messages keep flowing while InMails are paused, and it prevents a doomed call burning your per-account API budget. Sales Navigator credits also fully reset on the 1st of every calendar month — that auto-clear is independent and stricter.

Why isn’t my campaign sending faster?

Every LinkedIn campaign in WarmySender passes through a stack of caps before each action fires. Sending throttle is never the result of a single number — six independent caps are evaluated for every send, and the LOWEST one wins. The Throttle Diagnostic panel on the campaign detail page surfaces which cap is binding right now so you do not have to reason about the stack manually.

The cap stack — in evaluation order

  1. LinkedIn safe rates (per-account ceiling). The documented top-of-band per LinkedIn plan. Free = 0 InMails / 100 invites per week. Premium = 25 InMails / day, 100 invites / week. Sales Navigator and Recruiter = 50 InMails / day, 100 invites / week. These ceilings cannot be raised by any setting in WarmySender. See Account types & InMail credits.
  2. Account-type 4-week ramp. Even on a Sales Navigator account, week-1 starts well below the ceiling. Each calendar week after connection, per-action caps step up: invites 25 → 40 → 50 → 50, messages 75 → 100 → 125 → 150 (Sales Nav). The ramp protects new accounts from a hard restriction in the first month.
  3. Your chosen pace. Separate from the ramp above, and chosen when you connect the account based on how old and how active it is: a brand-new account eases in over about six weeks, an established one over about four, a long-standing one over about two, and an account recovering from a restriction takes the longest at around eight. You can also set your own pace, which skips the easing-in entirely. Your pace limits invites, messages, InMails, profile views and engagements per week, and whichever is lower — the ramp or your pace — is the one that applies.
  4. The daily amount you set on the campaign. The per-campaign budget you choose in the wizard. It counts every action together — one invite + one message + one InMail uses three of that day’s budget.
  5. A separate ceiling for each action type. Invites, messages, InMails and profile views each have their own daily ceiling on top of the campaign budget. Reaching one of them holds back ONLY that action type — the campaign carries on sending the others.
  6. The weekly invite ceiling on the account. Around 100 invites a week, and a Sales Navigator account can stretch further. The week resets every Monday at 00:00 UTC. This is the most common reason for “my campaign has gone quiet until next week”.
  7. InMail credits. Sales Navigator includes 50 InMail credits a month, Premium includes 5, Recruiter 100+. When LinkedIn says there are no credits left, we pause InMail steps on that account until LinkedIn refills them (the top of the next calendar month on Sales Navigator). Invites and regular messages keep flowing throughout, and InMails restart on their own.
  8. A safety rest after LinkedIn signals a limit. When LinkedIn tells us an account has hit one of its limits, we pause every action type on that account for a few hours so it can rest. Sending restarts automatically — you do not need to do anything. Trying again during the rest only extends it, because each further attempt counts against the account. Full explanation: Why did my LinkedIn invites pause today?

Worked example — a long-standing Sales Navigator account, week 4

You have one Sales Navigator account set to the fastest pace (its two-week easing-in is finished) and a campaign set to 50 a day, running invite-only steps, Mon-Fri, 09:00-17:00 UTC.

Cap layerValueEffective per day
LinkedIn safe rate (Sales Nav, paid)100 invites / week~14 / day (spread)
Account-type ramp (week 4)50 invites / day50 / day
Your chosen pace (fastest, week 4)200 invites / week29 / day
Weekly invite ceiling on the account200 / week29 / day
Daily invite ceilingthe weekly figure spread over 7 days29 / day
The daily amount you set on the campaign50 / day50 / day
The one that appliesthe lowest row29 invites / day

The Throttle Diagnostic panel will say: “Daily invite cap reached — resumes tomorrow at midnight UTC” once 29 invites have gone out, even though the campaign is set to 50. The narrowest limit always wins. Raising the campaign to 100 a day would NOT help — your pace and the weekly ceiling still top out at 29 invites a day. To send more: (a) wait for the easing-in to finish and the weekly ceiling to widen, or (b) add MORE LinkedIn accounts to the campaign, so each one works within its own allowance.

Common diagnostic outputs & what to do

What the panel saysWhat to do
Daily send limit reachedWait — it resets at midnight UTC. To raise it, edit the campaign and increase the daily amount, but that only helps if the per-action and weekly ceilings still have room.
Invite cap reached for this weekWait until Monday — the week resets at 00:00 UTC. Or add another LinkedIn account to the campaign, since each one has its own weekly allowance.
InMail credits exhaustedTop up credits in LinkedIn. Sales Navigator refills 50 a month at the top of each calendar month. InMails restart on their own — on the first one that goes through, or when the month rolls over. InMail steps are skipped meanwhile; invites and messages keep flowing.
View profile cap reachedWait — it resets at midnight UTC. Viewing a profile is a gentle action, and campaigns rarely rely on it as a required step.
Account on conservative ramp (week N of M)Wait one calendar week, or change the pace under Settings › LinkedIn. Moving a brand-new account to the fastest pace mid-flight is allowed, but it raises the risk of a restriction on accounts less than six months old.
Account in LinkedIn cooldownWait — do NOT retry by hand. Every attempt during the rest period extends it. The panel shows the exact time sending restarts, and it restarts on its own. See Why did my LinkedIn invites pause today?
Sending normallyNo action. The campaign is going as fast as it safely can. To send more: add more LinkedIn accounts, or wait for the easing-in to finish.

Why the panel names only ONE limit

People used to see a campaign’s daily budget only 30% used, assume something was broken, and write in — when in fact a different, lower limit (usually the weekly invite ceiling) was the real one holding things back. So the panel deliberately names ONE limit, choosing the one that holds sending back for the longest: a safety rest first, then the weekly ceiling, then the daily one, then the easing-in. The per-action rows underneath let you check the arithmetic yourself.

Account-safety contract

The Throttle Diagnostic is a UX hint — it does NOT influence dispatch decisions. The actual gate is enforced on the server side. The diagnostic helper makes ZERO LinkedIn API calls and ZERO new database writes — it reads from the same data the campaign detail page already loads. Account safety always wins over throughput.

Related

Acceptance vs reply tracking

Definitions

Example timeline A — accepted, then a follow-up message, then a reply

Day 0  09:00   Step 1 invitation sent
Day 2  14:12   Accepted
Day 3  09:00   Step 2 follow-up message sent
Day 5  17:42   They replied

At Day 5: accepted = 1, replied = 1, time from accept to reply = 3d 3h

Example timeline B — the reply reaches us before the acceptance does

Day 0  09:00   Step 1 invitation sent
Day 0  09:18   Reply reaches us at 09:18:42; acceptance at 09:18:48

Both are recorded:
  Accepted  09:18:48
  Replied   09:18:42

When someone accepts and replies within seconds, the two signals can reach us in either order. Both are still recorded, so your accepted and replied counts are both right. The prospect’s status shows replied rather than connected, because replying is further along than connecting — the counts and the status are tracked separately, so neither one loses information.

Daily send limit and LinkedIn capacity

Each campaign has a Daily limit setting that caps how many actions the campaign can take per day. For LinkedIn campaigns the right value depends on your account's tier and ramp strategy: a Sales Navigator account can sustain ~28 invites/day plus messages and profile views, while a brand-new Free account should stay below 80 actions/day. If your campaign's daily limit is set below what your account can produce, the cap becomes the binding constraint and your campaign will throttle below LinkedIn's safe production rate. WarmySender now picks a tier-aware default at campaign creation and shows a warning banner on the campaign detail page when the cap is below the account's expected daily capacity.

Recommended daily limit by account tier

LinkedIn account tierRecommended daily limitWhy
Free75/dayConservative ramp; no InMails; LinkedIn watches free-account volume closely.
Premium150/dayHeadroom for invites + messages + profile views; ~5 InMail credits per month.
Sales Navigator250/day200 invites/week + 100 profile views/day + up to 50 InMails/day fits inside.
Recruiter250/daySame daily-action ceiling as Sales Navigator on the safe band.

How the smart default is computed

When you create a LinkedIn campaign and don't set the daily limit yourself, WarmySender picks a default using the formula (maxInvitesPerWeek / 7) × 2 + 50, rounded to the nearest 25 and clamped to the per-tier safety bounds in the table above. The ×2 + 50 headroom covers messages, profile views, and engagements that share the daily budget alongside invites. Your account's per-account ramp gate is still the master ceiling — this default just makes sure the campaign cap doesn't strangle a healthy account.

If you really want a low limit

The server refuses to save a daily limit that's below your account's expected daily invite rate, because it almost always means you'll under-utilize your account. If you have a reason to keep the cap intentionally low (e.g. testing a single-prospect drip), pass ?force_low_limit=1 on the API request, or raise the limit and use a smaller prospect list instead.

Merge Tags & Personalization

Merge tags personalize each email by inserting prospect, sender, and campaign data at send time. They work in the subject line and body of every campaign step, and use Liquid syntax: {{ tag_name }}.

Supported merge tags

TagDescriptionExample
{{first_name}}Contact's first nameJohn
{{last_name}}Contact's last nameDoe
{{email}}Contact's email address[email protected]
{{company}}Contact's company nameAcme Inc
{{title}}Contact's job titleCEO
{{city}}Contact's cityNew York
{{country}}Contact's countryUSA
{{industry}}Contact's industryTechnology
{{sender_name}}Sender's display nameSales Team
{{sender_email}}Sender's email address[email protected]
{{sender_company}}Sender's company nameAcme Inc
{{signature}}Mailbox email signatureBest regards, John
{{company_address}}Company physical address (CAN-SPAM)123 Main St, City, ST 12345
{{campaign_name}}Campaign nameQ1 Outreach
{{custom.fieldName}}Any custom field on the prospect (from CSV){{custom.icebreaker}}

Aliases

Both {{first_name}} and the camelCase alias {{firstname}} work — same for {{last_name}} / {{lastname}}. Pick whichever style your team prefers and stay consistent inside a single template.

Filters (Liquid)

You can chain Liquid filters onto any merge tag. The most useful one is default, which provides a fallback when a field is missing on a prospect:

Hi {{first_name | default: "there"}},

Other supported filters: upcase, downcase, capitalize, truncate, strip.

What NOT to do

Don't put placeholder text inside {{ }}. The double curly braces are reserved for merge tags. Writing {{people/ops/talent}} will cause a template error and pause your campaign with reason template_error.

Use plain text for fill-in placeholders (e.g. write people/ops/talent directly in the body), or use a real merge tag ({{title}}) backed by a CSV column.

Examples

Subject line:

Quick question for {{first_name}} at {{company}}

Renders as: Quick question for John at Acme Inc.

Opening line with fallback:

Hi {{first_name | default: "there"}}, I noticed {{company}} recently expanded into {{city | default: "your region"}}.

If first_name is missing on a prospect, the email opens with "Hi there," instead of "Hi ,".

Custom CSV field:

{{custom.icebreaker}}

Would a quick 15-min call next Tuesday work?

Any CSV column you upload becomes available as {{custom.<columnName>}}. You can make EVERYTHING a variable — subject, first line, entire paragraphs.

Warmup Pipeline Health

How the dashboard counter, deliverability stats, and pause reasons work — read this if your warmup numbers look surprising.

Daily counter — what "today's sends" really means

The warmup dashboard shows a Sent today tile per mailbox. It goes up by one every time a warmup message successfully leaves that mailbox. It resets to zero at your mailbox's local midnight — not at global UTC midnight — so a Pacific-time mailbox rolls over at 00:00 PT (08:00 UTC) and an Australian mailbox at 00:00 AEST (14:00 UTC the day before). It only ever resets once per day, whatever else is happening.

Example: on Friday at 9 am Pacific your dashboard might show 12 sent; by 6 pm Pacific the same day you will typically see 30+ as more sends complete throughout your warming window. The number only ever grows during the day and resets cleanly at your local midnight.

During the day, the counter may briefly diverge from the per-mailbox event log by one or two if the engine is mid-flight between "message sent" and "counter incremented." Both writes happen inside a single transaction, so the drift never exceeds the in-flight count and self-corrects within seconds. The dashboard API also reconciles the displayed value against the event log so a stale counter can never display a wildly wrong number.

Deliverability lag — why the inbox/spam % grows during the day

After a warmup message is sent, the recipient mailbox needs a few minutes to receive it, the IMAP scanner needs to discover it in the INBOX or SPAM folder, and the engine then records the placement. The full cycle typically takes 3–30 minutes from send to detection, but can stretch to a few hours during heavy provider load. This means the Inbox % and Spam % metrics on the dashboard reflect completed detections, not just sends — so they will visibly climb throughout the day as the morning's messages get scanned.

If you check at 9 am you might see 30 sent but only 8 detected, giving a deliverability metric based on those 8. By 6 pm the same day, the same metric typically reflects 25–30 detections out of 30 sent — a much more accurate picture. Never panic over an inbox % computed before lunch; let the day complete before drawing conclusions.

Why warmup paused — reading the pause reason

When warmup stops on a mailbox, the system records a structured pause reason that tells you exactly why. Reasons fall into two broad groups: billing (your subscription or trial cannot keep funding warmup) and technical (the mailbox itself is failing). Resume the right way for each.

Why it pausedWhat it meansHow to resume
Your free trial endedWarmup needs an active plan behind it, so it pauses when a trial finishes without one. Your campaigns stop sending at the same time, and everything you built is kept exactly as it is.Pick a plan under Billing. Warmup and your campaigns come back on their own a few minutes after the payment goes through — your warmup progress is kept, so you don't restart the ramp from day one.
An invoice is outstandingYour most recent payment did not go through. Warmup pauses while an invoice is unpaid, so we never warm a mailbox without an active plan behind it. Your campaigns pause with it.Settle the invoice under Billing. The banner there names it and says whether your bank needs to approve the charge, the card needs replacing, or the payment is still being processed. Once it clears, warmup and campaigns restart on their own within a few minutes, with your progress kept. There is nothing to press — and switching warmup on yourself beforehand will not work, because warmup needs an active plan.
Your plan endedThe subscription was cancelled, or an unpaid invoice was never settled and the retries ran out.Choose a plan again under Billing. Your mailboxes, prospects and campaign data are all retained; warmup resumes within a few minutes of the new plan starting.
Your inbox credentials stopped workingThe username, password or app password we hold for this mailbox no longer signs in — usually because it was rotated, revoked, or two-factor settings changed at your email provider.Reconnect the inbox. Mailboxes › click the affected row › Reconnect. As soon as the new credentials test successfully, the pause clears and warmup carries on.
Repeated sign-in failuresSeveral failed sign-ins in a row triggered an automatic safety pause, so we stop retrying a credential your provider is already rejecting.Reconnect the inbox — same path as above. The pause clears the moment the reconnect test passes; there is no waiting period and nothing else to do.
Outgoing mail is switched off at your providerYour email provider has switched off outgoing mail for this account, so it refuses every email the mailbox tries to send. Signing in and reading the inbox still work, and your username and password are fine.Turn outgoing mail back on in your provider's control panel, or ask their support to. We try one test email at a growing interval (up to once a day), and warmup starts again on its own as soon as one goes through.
Your provider is refusing our sending serversYour email provider is temporarily refusing connections from our sending servers, so warmup emails from this mailbox can't go out for now. Nothing on your side causes this.Nothing to change. We try one test email at a growing interval (up to once a day), and warmup starts again on its own as soon as one goes through.
Someone turned warmup offYou, or a teammate on your workspace, switched warmup off for this mailbox.Turn it back on from the Warmup page. There is no cooldown. One thing to know: this works while your plan is active — if there is an unpaid invoice or no plan on the account, the switch is refused until that is sorted out first.

If a mailbox shows warmup active in the UI but is generating zero sends and zero detections, look at the per-mailbox detail page first — the pause reason will be displayed there even if the high-level toggle still reads on.

I fixed my billing but my warmup is still paused — what should I do?

When a renewal payment doesn't go through, WarmySender pauses warmup on your mailboxes. This is a deliberate safety pause: we never warm a mailbox without an active plan behind it, because warming an inbox you're no longer paying for can do more harm than good to your sender reputation. The same rule applies across every channel on the platform — cold email campaigns, email warmup, LinkedIn, Instagram, and multichannel sequences all wait for an active plan before they run.

Once your payment clears and your subscription is active again, warmup resumes automatically within a few minutes — you don't need to restart anything, and your earlier warmup progress is preserved, so your mailboxes pick up where they left off instead of starting the ramp from day one. To clear the pause: update your card under Billing › Payment Method, confirm the payment goes through, and give it a few minutes.

Settling the invoice is the only thing that clears this, and it is worth saying plainly why. Switching warmup back on yourself first does not work: warmup needs an active plan behind it, so the switch is refused while an invoice is outstanding — and if it did flip on, a routine check would restore the pause a few minutes later. Rather than leave you pressing a button that cannot succeed, we would rather tell you: pay the invoice, then wait a couple of minutes and everything returns by itself. If a mailbox is still paused well after your payment has cleared, open its per-mailbox detail page to see the current reason, or contact us at warmysender.com/support.

When in the day does warmup send?

Warmup runs around the clock. We deliberately spread your warmup messages across all hours of the day rather than confining them to set "office hours" — genuine inboxes receive mail at every hour, so steady round-the-clock activity looks more natural to inbox providers than traffic squeezed into a narrow daily window. Because of this, warmup has no per-hour send window to set: every enabled mailbox automatically sends a small, steadily-ramping number of messages spread throughout the day.

What changes over time is the number of messages per day, which ramps up gradually as your mailbox builds reputation (see the ramp section below) — not the hours they go out in. Time-of-day control for your own prospect outreach is set per campaign, separately from warmup.

Ramp — how the daily amount grows over time

A brand-new mailbox does not start at the daily amount you set. It starts low — typically 5–10 messages on day one — and climbs a little each day toward your target. How quickly it climbs depends on the situation the mailbox is in and on how healthy it has been (spam rate, bounce rate, and where its mail lands):

Once a mailbox reaches steady maintenance — roughly 14 days in, with clean health — its daily amount settles at the target you set. If its health slips, we lower the daily amount by ourselves for a while. That is deliberate protection, not a fault, and it lifts again as the numbers recover. More detail: How email warmup ramps up, how to control your warmup sending volume, and why your warmup volume went down.

Sending vs receiving — what the Inbox Rate does and does not tell you

Your Inbox Rate is a sending score. It measures the warmup mail this mailbox sent and how much of it landed in the main inbox of the people receiving it. It says nothing at all about what arrives at this mailbox. Those are opposite directions, and they are measured separately.

That is why a mailbox can honestly read 99% and "Excellent" while nothing has arrived at it for two weeks. Both facts are true at once: its outgoing mail is landing beautifully, and its incoming side is stalled. The sending score is still the number that predicts whether your cold email campaigns reach the inbox — it is just not the answer to "am I receiving?".

To answer that one, read the note on the individual mailbox rather than the headline score:

The whole picture, with worked examples: My inbox rate looks great but I’m not receiving warmup emails and Understanding your warmup Inbox Rate.

When numbers look surprising — quick diagnostic checklist

  1. Check the time zone. If "Sent today" looks higher than expected, confirm the mailbox's time zone setting matches where you actually are — the wrong time zone can make "today" stretch across up to 48 hours of real sends.
  2. Wait until end-of-day. Deliverability % grows throughout the day as detections complete. Morning numbers under-report; end-of-day numbers are accurate.
  3. Read the pause reason. If sends are zero, the per-mailbox detail page shows exactly why — match the reason against the table above.
  4. Reconnect if needed. Almost every technical pause clears with a successful Reconnect from the Mailboxes page; you do not need to contact support first.
  5. Be patient on day one. A new mailbox is intentionally throttled by the ramp; a low send count on day one is the platform protecting your domain reputation, not a failure.

Need More Help?

Contact us at warmysender.com/support — 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.

Frequently asked questions

How do I connect my email account to WarmySender?

Go to Mailboxes > Add Mailbox. For Outlook/Microsoft 365, click 'Connect with Microsoft' to sign in with OAuth. For Gmail/Google Workspace, connect with an app password over IMAP/SMTP — turn on 2-step verification, generate an app password, and paste it into the connect form. Other providers connect with IMAP/SMTP credentials the same way.

How do I start email warmup?

After connecting your mailbox, go to Warmup Settings and toggle warmup ON. Set your daily warmup volume (we recommend starting at 5-10 emails/day) and WarmySender will automatically send and reply to warmup emails.

How do I create a cold email campaign?

Go to Campaigns > Create Campaign. Add your prospect list, write your email sequence (up to 7 steps), set sending schedule and timezone, then activate the campaign.

How do I set up LinkedIn automation?

Purchase a LinkedIn seat add-on ($12/seat/month), then go to LinkedIn > Connect Account. You can connect with a browser cookie or with your LinkedIn email and password. Everything runs on our servers, so there is no browser extension to install and nothing plugs into your browser session.

What email providers does WarmySender support?

Gmail, Google Workspace, Outlook, Microsoft 365, Yahoo, Zoho Mail, Hostinger, iCloud, Fastmail, ProtonMail, and any provider with IMAP/SMTP access.

How do I check my email deliverability?

Go to your Mailbox dashboard to see inbox placement rate, warmup score, and sender reputation. WarmySender tracks these metrics automatically for all connected mailboxes.

How do I import prospects for campaigns?

Go to Prospects > Import. Upload a CSV file with columns for email, first name, last name, and company. You can also add prospects manually or use the built-in B2B lead database.

What is Bounce Shield and how does it work?

Bounce Shield is WarmySender's built-in email verification. It checks prospect addresses before sending and holds back the ones confirmed undeliverable, removing most avoidable bounces and protecting your sender reputation. It runs automatically on campaign activation. Verification reflects the moment it runs, so a verified list can still bounce a little.

Why is LinkedIn enrichment taking so long?

Enrichment is rate-limited to protect your LinkedIn account. Daily caps range from 10-100 profiles/day depending on account age and strategy. New accounts start at ~10/day and increase each week. You can start campaigns immediately without waiting for enrichment.

Why does enrichment use my LinkedIn account instead of a system account?

LinkedIn requires an authenticated session to view profiles — there is no public API. A shared system account would be banned within hours. Using your own account also provides network-specific data like connection degree. All LinkedIn automation tools work this way.

Can I start a LinkedIn campaign without enrichment?

Yes. Campaigns only need LinkedIn profile URLs to function. Enrichment adds extra data (name, company, headline) for personalization but is completely optional. Create and launch your campaign immediately — enrichment runs in the background.

My LinkedIn enrichment failed — what should I do?

Common causes: the LinkedIn account disconnected part-way through, too many errors in one day (we stop enrichment for the day to protect your account), or the audience was deleted. Reconnect your LinkedIn account, go to Audiences, and click Restart Enrichment. Previously enriched profiles are cached.

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

This was a real bug, fixed in late April 2026. Earlier, a campaign could be paused without recording a pause reason, so the auto-resume sweeper couldn't tell whether the underlying issue (account disconnect, high failure rate, etc.) had cleared. The fix records a structured pause reason on every pause and rejects any future regression at the database layer. Open the campaign detail page and look at the pause reason — it now always tells you why the pause happened (account disconnected, high failure rate, subscription canceled, etc.). If the field is still empty, your campaign predates the fix; click Resume once and the system will re-evaluate the row, populate a reason if there's a real cause, or move it back to running if not. Your prospects, sequences, and analytics are completely untouched by the fix.

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

Sales Navigator URLs (the form `https://www.linkedin.com/sales/lead/ACoAAA...,NAME_SEARCH,XYZ`) sometimes can't be resolved to a public LinkedIn profile. This happens for restricted profiles, recently-deleted leads, and a known issue with certain `,NAME_SEARCH,` query suffixes. Before late April 2026, when resolution returned nothing, our campaign engine treated the prospect as 'cannot be invited, mark complete' — silently completing the prospect with zero invite attempt. The fix shows affected prospects as Unresolved URL and retries with exponential backoff up to 5 times before promoting to a terminal Failed state. They never complete silently again. To recover prospects affected by the old behavior: re-import them with regular `linkedin.com/in/<handle>` URLs (most reliable), or run the recovery routine which automatically re-stamps eligible prospects so they re-enter the queue on the next campaign tick. Your campaign config and other prospects are untouched. If you're unsure whether your import is affected, contact support — we can check the resolver outcome for any prospect by ID.

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 the weekly invite counter on your account: a standalone engine (LinkedIn-only campaigns) and a unified multichannel engine (campaigns combining email and LinkedIn steps). Both engines hit the same shared counter, but campaign activity is tracked separately per engine. 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's never wrong. To see total invites across both engines for an account, the LinkedIn Accounts dashboard now shows invites sent this week vs. weekly limit directly (engine-agnostic). If the numbers still don't add up after a 5-minute refresh, contact support — we can run a canonical diagnostic.

Why am I getting 'reconnect needed' emails when my LinkedIn is showing connected?

This is a stale health flag left over from a prior upstream outage. Your account is genuinely connected and our system is communicating with LinkedIn fine — but a derived health marker didn't reset when the reconnect succeeded, and our daily alert-email job kept firing on it. The late-April 2026 fix makes this permanent: the reconnect path now resets the health marker alongside the other recovery markers, the alert email is gated to skip any connected account, and a drift sentinel surfaces any future regression to admins before customers see it. If you still see the email after the fix is deployed, click Reconnect once from LinkedIn → Accounts (your campaigns and prospects are untouched) and the flag will reset cleanly.

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

This was a real bug, fixed in late April 2026. Reply detection was relying on a campaign attribution that wasn't being populated on inbound LinkedIn messages — neither the webhook ingest path nor the polling fallback was running the attribution lookup before storing the message. Net: every inbound LinkedIn message landed in the database with no campaign attribution, the dashboard reply count, auto-stop-on-reply check, and analytics reply-rate roll-up all silently filtered them out, and the dashboard showed 0 replies even when prospects had clearly responded. Worse: campaigns kept sending follow-ups to prospects who'd already replied. The fix adds an attribution lookup that the webhook handler and the polling fallback both run before recording inbound messages — 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 unattributed rows. Reply stats refresh within 1 hour after the backfill runs. If you still see drift after that window, contact support — we can re-run the backfill against your specific workspace.

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

No — late-April 2026 fix. Previously, every Profile-inaccessible response from LinkedIn was treated as terminal and the prospect was completed with no further retry — even though that response conflates several distinct cases, including some that are recoverable on a re-resolve (Sales Navigator URLs that didn't resolve on attempt N but resolve cleanly on attempt N+1, and URL canonicalization issues fixed by a related ID-aware fallback). The platform-wide audit found 21,868 enrollments completed this way. The fix migrates all of these to a defer-not-burn flow: the prospect's status flips to Pending Resolution instead of terminal Failed, the engine retries with exponential backoff capped at 5 attempts before promoting to terminal Failed, and the 21,868 historical rows were swept into the same recovery flow with their re-attempts spread over a 24-hour window so the queue doesn't slam LinkedIn rate limits. If you see this status: please verify the prospect's LinkedIn URL is current (regular `linkedin.com/in/<handle>` URLs resolve most reliably), and click Retry on the prospect detail page. The defer flow handles the recovery automatically — no further action needed unless you see the prospect repeatedly land back in Pending Resolution after 5 retries (which would indicate a genuinely-terminal restricted profile).

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 LinkedIn integration. Important first: every reply is still safely in your LinkedIn inbox — nothing is lost on LinkedIn's side. The gap is purely between our integration and WarmySender, not between you and your prospect. When webhook delivery stalls, the inbound message still reaches our database via a 30-minute polling fallback, but the dashboard side-effects that the webhook normally triggers (the 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 already replied. Our detection infrastructure catches this within 15 minutes: a webhook health monitor compares the rate of inbound messages landing in our database against the rate of webhook events received, and raises an internal alert when the ratio drops. The runbook then lets us (1) escalate to restore the webhook, (2) confirm the polling fallback is bridging the gap at 30-minute cadence, and (3) once the webhook is back, run an idempotent replay backfill that re-drives the missed reply state-flips from the locally-stored inbound rows. The replay retroactively applies stop-on-reply, so dashboard counters reflect ground truth within ~1 hour of recovery. The detection and replay layer makes zero LinkedIn API calls — account safety always wins. If you suspect this is happening to your workspace, contact support at https://warmysender.com/support with a sample prospect URL and approximate reply timestamp; we can verify the per-account state and confirm the recovery timeline.

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

Late-April 2026 fix. 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 depending on the era: render the message with a literal 'undefined' and send anyway (rude), or complete the prospect as Failed with no recovery path. 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, so you can either fix the typo, edit the template to remove the missing variable, or re-import the CSV with the column populated. (2) Defer-at-send — if a template variable somehow still unresolves at send time (race: campaign launched, then the audience had a column dropped before the send fired), the runtime renderer now parks the prospect as Pending Template Variable Resolution instead of completing as Failed. 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 recovery needed. If you see this on existing prospects: either edit your template to remove the missing variable, or re-import the CSV with the column populated, then click Resume — those prospects will retry within a campaign tick.

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

Three scenarios: (1) The LinkedIn account was disconnected at the moment the follow-up was supposed to fire — the engine cannot send through a disconnected account (account safety always wins) and parks the enrollment until you reconnect. The auto-resume sweep wakes parked enrollments within 5-10 minutes of reconnect. (2) The follow-up step was a 'wait for acceptance' condition that already evaluated and routed the prospect down the false branch because the wait window expired before the acceptance landed — this is the campaign's correct end state per how you configured it. (3) Silent skip from a worker race or a campaign edit mid-flight — the genuinely-stuck pattern. Symptom: the prospect shows accepted but no follow-up message went out and no error event was recorded. We ship a periodic post-acceptance enqueue helper and an orphan-job reconciler that catches these and recreates the missing send job. In late April 2026 we ran a one-shot backfill against a 422-row cohort. If you suspect a stuck row, contact support at https://warmysender.com/support with the prospect URL — we can manually re-arm the enrollment. The recovery flows make zero LinkedIn API calls.

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

Replies imply acceptance — you can't reply to a message unless you accepted the invite first. Two issues caused this. Issue 1 (fixed late April 2026): a fast-reply race where prospects accepted and replied very quickly; the old code skipped the acceptance timestamp because the row had already advanced past Invited. Fix: split the timestamp stamp from the status flip so even a fast-reply row gets its acceptance recorded for the dashboard. Issue 2 (fixed late April 2026): some analytics surfaces (the 24h freshness banner on LinkedIn → Accounts, per-account analytics roll-up) read a different event store from the campaign counter. After the engine consolidation, unified-engine campaigns wrote acceptance events to the campaign store but never mirrored to the account-level store, so the banner showed 'no accepts in 24h' even when accepts were flowing. Fix: idempotent paired insert from the canonical helper covers both stores. The campaign-card Accepted/Replied counters and the LinkedIn Accounts banner now show consistent numbers. Hard-refresh your dashboard if you still see the issue (60s cache); contact support if accept rate is 0% with replies present after the deploy date.

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

Your campaign's message template has a Liquid syntax error — most commonly a typo in a merge tag like {{company} (one closing brace instead of two). Liquid requires EXACTLY two opening braces and two closing braces around every variable: {{firstName}}, {{company}}, {{custom.subject_line}}. Before late-April 2026, this triggered an infinite retry loop — one early customer campaign had 28 follow-up jobs retrying continuously with the same '{{company}' typo until we shipped the dead-letter fix. After the fix: the engine detects the parse-error on the first attempt; the send job is marked Failed with a template-syntax-error classification; the enrollment is parked as Pending Template Fix so the orphan reconciler does not recreate the job. To fix: open the affected campaign, find every merge-tag reference and verify each has exactly TWO opening braces and TWO closing braces (common typos: {{firstName}, {firstName}}, { {firstName}}, {{firstName | default: 'there'}). Save and click Resume — affected prospects retry on the next campaign tick. No prospects are lost. No LinkedIn API calls were made on the failed attempts (the parse error fires before the LinkedIn call), so no rate-limit cost to retrying. Click Preview in the editor to see the exact line number of the parse error.

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

If LinkedIn → Accounts 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 account-level dashboard tile is just under-reporting unified-engine sends. Why (late-April 2026): there are two campaign engines — a standalone engine and a unified multichannel engine. Both call the same shared counter for weekly rate-limit gating (always correct, load-bearing for safety, never under-reports), but the daily-bucket tiles were written by a separate post-success increment that the unified engine forgot to wire on some action sites. Sources of truth: the weekly counter (drives rate-limit gating) is always correct; the campaign-card daily counter is always correct; the account-card daily counter under-reports for unified-engine campaigns until the fix is deployed. To verify messages went out: open the campaign card and check the per-step activity counter (ground-truth); open the LinkedIn inbox and confirm the messages are visible; check the last-messaged timestamp on the prospect. The fix audits every unified-engine action site and adds the paired daily-counter increment in the same transaction; a one-shot backfill recomputes the daily buckets from event rows. One customer's dashboard showed 1 message sent on the morning of the fix day even though 24 messages had legitimately gone out — every send was real, every safety gate held, the counter just lagged. Contact support if counters still mismatch after the fix lands.

I fixed my billing but my warmup is still paused — what should I do?

When a renewal payment doesn't go through, WarmySender pauses warmup on your mailboxes. This is a deliberate safety pause — we never warm a mailbox without an active plan behind it, because warming an inbox you're no longer paying for can hurt your sender reputation rather than help it. The same rule applies across every channel on the platform: cold email campaigns, email warmup, LinkedIn, Instagram, and multichannel sequences all wait for an active plan before they run. Once your payment clears and your subscription is active again, warmup resumes automatically within a few minutes — you don't need to restart anything, and your earlier warmup progress is preserved, so your mailboxes pick up where they left off instead of starting the ramp over from day one. To clear the pause: update your card under Billing › Payment Method, confirm the payment goes through, and give it a few minutes. Prefer not to wait, or want to switch it back on yourself? Open the Warmup page and toggle each affected mailbox back on manually — it takes effect immediately and your warmup progress is still kept. If a mailbox stays paused well after your payment has cleared, open its per-mailbox detail page to read the current pause reason, or contact us at https://warmysender.com/support.