Bulk messaging is a probability game played against platform anti-abuse systems. The platforms (Telegram, X, WhatsApp) maintain a hidden per-account trust score updated in near-real-time based on send volume, send timing, message similarity, recipient reports, recipient blocks, and a dozen other signals. Drop below a hidden threshold and the account is restricted, suspended, or banned.
The job of this guide is to give you the operating ranges that keep trust scores stable. Stay inside the ranges, run for years. Cross them, and you lose the account.
Step 1: Calculate your realistic daily throughput
The formula:
daily_safe_volume = warm_accounts × per_account_daily_ceiling × (1 - opt_out_buffer)
# Worked example
warm_accounts = 5
per_account_daily_ceiling = 50 # for accounts 30+ days old, post-warmup
opt_out_buffer = 0.10 # reserve 10% capacity for replies, opt-outs
daily_safe_volume = 5 × 50 × (1 - 0.10) = 225 outbound DMs/day
weekly_volume = 225 × 7 = 1,575
monthly_volume = 225 × 30 = 6,750That is the realistic envelope. If your campaign plan calls for 10,000 DMs in a week from a 5-account fleet, the math says no; you will either burn accounts or take three weeks. Resize the campaign or add accounts before launch.
The per-account daily ceiling table:
- Account age 0-7 days: 5/day max.
- Account age 8-14 days: 15/day max.
- Account age 15-30 days: 30/day max.
- Account age 30+ days, warmed up: 50/day standard.
- Account age 90+ days, strong history: up to 100/day for short bursts.
These are not Telegram's published limits (Telegram does not publish any). They are the empirical safe envelopes we have observed across thousands of production accounts over multiple years. Stay below them and your trust score is stable. Push them and you start collecting flood-waits.
Step 2: Set up the rate limiter per account
CRM Solid's rate limiter is per-account, with three knobs and an optional schedule:
- per_hour: maximum sends per rolling 60-minute window.
- per_day: maximum sends per UTC calendar day.
- min_interval_seconds: minimum gap between two consecutive sends from the same account.
- business_hours_only: restrict sends to a configured local timezone's 9 AM - 7 PM window.
The recommended defaults by account age:
Account age per_hour per_day min_interval business_hours
0-7 days 2 5 60s on
8-14 days 5 15 45s on
15-30 days 10 30 20s on
30+ days 20 50 10s on (recommended)
30+ days, busy 40 100 8s off (advanced)The "advanced" row is for established accounts running a high-volume support inbox in addition to outbound; they have organic traffic that justifies higher rates. Most accounts should stay on the 30+ days standard row.
Step 3: Build spintax variation into every template
Platforms run content fingerprinting across messages from the same account and across multiple accounts on the same network. If 200 DMs in 48 hours all start with the same eight words, the content fingerprint matches and your trust scores drop together.
Spintax defeats this signal by varying the message body deterministically per send. The syntax is {option1|option2|option3}. CRM Solid resolves it at send time so every recipient receives one randomly-picked variant.
# Weak spintax (do not do this)
{Hi|Hey|Hello} {there|friend|buddy}!
# Strong spintax (every variant reads naturally)
{Hi {first_name}|Hey {first_name}|Hello from London, quick one for {first_name}}
- {noticed your post|saw your comment|caught your latest tweet} about
{topic} {today|earlier|yesterday}.
We help {persona} solve that without
{spending six months in spreadsheets|paying enterprise prices|building it in-house}.
Quick check - are you {actively looking|just researching|on the side}
for that right now?The four rules of strong spintax:
- Each variant is a complete natural sentence on its own. Read every variant out loud. If any sounds broken, rewrite.
- Vary structure, not just adjectives.
{great|awesome|amazing}is shallow; varying the sentence shape ("Quick one, vs Hi {first_name}, vs Hey,") creates real lexical diversity. - 4-8 variants per spintax block. Below 4, the alternation collapses to noticeable repetition under load. Above 8, you struggle to keep them all coherent.
- Combine spintax with merge variables.
{first_name},{company},{custom_field_1}: these are the strongest variation source because they are unique per recipient.
Step 4: Distribute across multiple accounts with round-robin
One account at 50/day caps your campaign at 50/day. Two accounts at 50/day each give you 100/day. The math is linear up to the point where multi-account behavior itself becomes a signal.
In CRM Solid, Sequences > New > Audience > Distribution offers four modes:
- Round-robin: recipients dealt one-by-one to accounts in rotation. Even load, simple to reason about.
- Weighted: recipients dealt proportionally to each account's configured weight. Useful when one account is older/stronger than the others.
- Geographic: recipients in EU go to EU-based senders, US recipients to US senders, etc. Higher relevance, fewer obvious-bot signals.
- Owner-bound: recipients with an assigned owner go to that owner's sender account. Best for warm follow-ups, terrible for cold (creates a hot-spot account).
For cold outreach with 5 senders of equal age, use round-robin. For mixed-age fleet, use weighted with weights proportional to account age (e.g., 90-day account = weight 3, 30-day account = weight 1).
Step 5: Warm up every new account before adding it
A fresh account dropped into a campaign at 50/day from day one is a banned account by day 4. The Telegram (and X, and WhatsApp) anti-abuse systems specifically watch for "young account, high cold volume" as the strongest possible spam signal.
The 14-day warm-up curve:
Day Daily target Pattern Notes
1 5 Send to your own personal contacts Pure warm
2 5 Reply to inbound, send 2 outbound Bias to inbound
3 8 5 warm + 3 opted-in subscribers First outbound to non-personal
4 10 7 opted-in, 3 warm Light-cold
5 12 10 opted-in, 2 cold Tiny cold test
6 14 12 opted-in, 2 cold Same, slightly more
7 16 12 opted-in, 4 cold Cold creeping up
8 20 15 opted-in, 5 cold Phase 2 starts
9 24 18 opted-in, 6 cold
10 28 20 opted-in, 8 cold
11 32 22 opted-in, 10 cold
12 36 22 opted-in, 14 cold
13 42 22 opted-in, 20 cold
14 50 22 opted-in, 28 cold Full ceiling reachedCRM Solid has a warm-up mode toggle on every account. When enabled, it caps sends to the day-N target on the curve, automatically incrementing daily. You set the start date, it manages the rest. Disable it after day 14, and the account graduates to standard rate limits.
Meanwhile, the account must look human:
- Profile photo set (use a real photo, not a stock image).
- One-line bio set in your operating language.
- At least 10 contacts in the address book.
- At least 5 organic 2-way conversations in the message history.
- Visible activity status (not "Last seen long time ago").
Step 6: Configure your flood-wait response policy
A flood-wait is Telegram's soft rate-limit error. The response includes a duration in seconds:FLOOD_WAIT_42 means "wait 42 seconds before retrying." CRM Solid handles this automatically, but you should configure the response policy.
Recommended settings in Settings > Outreach health:
- On first FLOOD_WAIT: pause account for X + 30% jitter, mark "recovering."
- On second within 6 hours: pause for X × 2 + 30% jitter, reduce per-hour cap by 50% for 24 hours.
- On third within 24 hours: stop the account for the day, send alert email to operator, suggest reviewing templates and segment.
- On any account-level suspension (PEER_FLOOD): pause for at least 24 hours, alert operator, do not retry automatically.
# Sample worker log
[14:02:18] Account #3 (alice_main): SENT to @user_4521 (#1247 of 250)
[14:02:31] Account #3: FLOOD_WAIT_55 received
[14:02:31] Account #3: pausing 71s (55 + 30% jitter)
[14:02:31] Worker: queued message #1248 re-dispatched to Account #1
[14:03:42] Account #3: resumed, per-hour cap reduced 50% for 24h
[14:03:42] Account #3: SENT to @user_2199 (#1248 of 250)Step 7: Launch a pilot batch and watch metrics
Never go from "draft" to "full campaign" in one click. Run a 50-message pilot first.
- Set the campaign daily cap to 50.
Launch. - Watch the outreach health dashboard for 60 minutes.
- Healthy targets:
- Reply rate ≥ 8%
- Bounce/error rate ≤ 2%
- Zero flood-waits
- Zero blocks (someone blocked your sender)
- Opt-out rate ≤ 1%
- If any of these are off, pause. Do not raise the cap. Investigate.
Step 8: Scale safely
After a clean pilot, raise the cap to your calculated daily safe volume (Step 1). Then watch the same metrics daily for the first week, weekly thereafter.
The early-warning signals to act on:
- Reply rate trending down 1%/week: template fatigue. Rotate in a fresh variant set.
- Block rate rising: audience targeting is too broad. Tighten the segment.
- Flood-wait spike on a single account: that account is hitting a per-window cap. Reduce its share of the rotation, give it a day off, then re-introduce at half load.
- Multiple accounts hit flood-wait same day: campaign-level signal. Telegram is throttling your whole fleet. Pause everything for 24 hours, then resume at 50% throughput.
Bulk messaging done right looks boring from outside: the same campaign quietly sends 225 personalized DMs every weekday for months, producing 20-30 replies and 5-8 demos every day, with zero ban events. That is the goal.