The Migration That Torched the List: Deliverability-First GoHighLevel Builds for Email and SMS Agencies
A 180,000-contact migration dropped open rates from 34% to 9% in a single send. The rebuild took eleven weeks and every step was preventable.
In short
For a lifecycle email and SMS agency, deliverability is not a technical sub-task of a GoHighLevel migration — it is the entire risk surface. When you move a client's list from Klaviyo, Mailchimp or ActiveCampaign into GHL, you are not moving data, you are abandoning a sending reputation that took years to build and starting a new one from zero on a domain and IP pool that no mailbox provider has ever seen. Sending 180,000 messages on day one from that cold posture is the single most common way agencies destroy a client relationship inside a fortnight, because Gmail and Microsoft respond to unfamiliar high-volume senders by routing them to spam and, once that classification sticks, it can take eight to twelve weeks of disciplined low-volume sending to unwind. The defence is unglamorous and entirely procedural — a correctly authenticated sending domain with SPF, DKIM and DMARC published and verified before a single send, a staged warm-up that starts around 200 messages a day and roughly doubles every second or third day across four to six weeks, engagement-ordered sending so your most active contacts carry the early reputation, A2P 10DLC registration filed weeks before the SMS launch date, and inbox-placement monitoring that tells you about a problem on day three rather than day thirty. Get that sequence right and the migration is invisible to the client's subscribers; get it wrong and no amount of copywriting skill will rescue the numbers.
Key takeaways
- A new sending domain has no reputation history with mailbox providers, so a full-list send on day one is treated as a spam signal regardless of how clean the list is or how good the content might be.
- A safe warm-up ramp starts at roughly 200 messages per day and doubles every two to three days, reaching full volume for a 180,000-contact list in approximately four to six weeks.
- SPF, DKIM and DMARC are three separate DNS records solving three separate problems — envelope sender authorisation, cryptographic message signing, and policy alignment — and Gmail and Yahoo have required all three from bulk senders above 5,000 messages per day since February 2024.
- A2P 10DLC brand and campaign registration for US SMS typically takes three to fifteen business days end to end, which means filing it the week before a scheduled launch guarantees a delayed launch.
- Engagement-ordered sending, where the first warm-up batches go only to contacts who opened in the last 30 days, produces higher early open rates and builds positive reputation faster than sending to a random sample of the same size.
If your agency's craft is lifecycle email and SMS, you already know something that most GoHighLevel content quietly ignores. The platform is not the hard part. Building a welcome series, an abandoned-cart flow or a win-back sequence inside GHL is a week of work for someone who has built the same flows forty times in Klaviyo. The hard part is that between the client saying yes to the migration and the first campaign going out, you are asked to move something that cannot be copied — the client's sending reputation.
That reputation is not in the export file. It lives in the memory of Gmail, Microsoft, Yahoo and a dozen smaller mailbox providers, attached to a domain and an IP range, built up over years of consistent, well-received sending. When you migrate, you leave it behind. The new domain starts at zero, and zero does not mean neutral. To a mailbox provider, an unknown domain that suddenly emits 180,000 messages in an afternoon looks exactly like a compromised account or a purchased list, because that is overwhelmingly what such behaviour usually is.
This post is about that risk and the specific, boring, sequenced work that eliminates it. It covers the DNS records you publish before anything else, the warm-up ramp by day and by volume, the A2P 10DLC timeline for SMS, how to decide which contacts survive the migration, and how to watch placement closely enough to catch a problem while it is still cheap to fix. It is written from the perspective of an agency doing this for clients, repeatedly, where a single bad migration does not just cost one account — it costs the reference that would have won the next three.
Why does deliverability decide whether a GoHighLevel migration succeeds?
Because deliverability is the multiplier on everything else you build, and when it goes to zero, everything else goes with it. A perfectly segmented lifecycle programme with best-in-class copy and a 40% inbox placement rate earns less than a mediocre programme at 95%. There is no flow design clever enough to compensate for messages that subscribers never see.
The asymmetry is what makes this the defining risk for email and SMS agencies specifically. Other agency types migrating to GHL are moving pipelines, calendars and forms — things that break loudly and get fixed the same afternoon. A deliverability failure breaks silently. Messages are accepted by the receiving server, reported as delivered by the platform, and quietly filed in spam. Your dashboard shows a 99.4% delivery rate. Your client's revenue shows something very different.
That gap between "delivered" and "seen" is where agencies lose accounts. Delivered means the receiving mail server accepted the message. It says nothing about which folder it landed in. If you are reporting delivery rates to clients as evidence that things are healthy, you are reporting a number that stays high right up until the moment the relationship ends.
The second reason deliverability decides the outcome is time. Most operational mistakes in an agency are recoverable in days. A damaged sending reputation is recoverable in weeks or months, and during that recovery the client's revenue is impaired the whole time. An eight-week recovery on a list that normally generates $60,000 a month in attributable email revenue is not an eight-week technical problem. It is a $200,000 to $300,000 problem, and it will be discussed in those terms.
The third reason is that the failure is entirely preventable. Every element of a safe migration is known, documented and mechanical. Nobody destroys a list because of an exotic edge case. They destroy it because they were under deadline pressure, the client wanted to launch on the first of the month, and the warm-up looked like something that could be compressed. It cannot.
What actually happens when you send a full list from a cold domain?
The collapse is not instantaneous, which is what makes it so dangerous. The first send usually looks acceptable, the second is visibly worse, and by the third the campaign is effectively invisible. By the time anyone raises an alarm, three sends of negative reputation data have already been recorded against the new domain.
Here is the mechanism. Mailbox providers do not have a single spam-or-not decision point. They have a continuously updated reputation score attached to your sending domain and IP, fed by signals including complaint rate, bounce rate, spam-trap hits, sending volume consistency, authentication results, and — most importantly — recipient engagement. A brand-new domain has no history, so early sends are evaluated conservatively and a much larger share is routed to spam or the promotions tab as a precaution.
That precautionary filtering is the trigger for the spiral. Messages in spam do not get opened. Low open rates are read as low engagement. Low engagement lowers the reputation score. A lower score means more aggressive filtering on the next send, which produces even lower engagement. Each campaign makes the next one worse, and the curve is steep because the feedback loop runs on every send.
Volume amplifies all of it. A cold domain sending 500 messages is a small unknown. A cold domain sending 180,000 is an anomaly that looks like abuse. Providers weight rate-of-change heavily, so the jump from nothing to full volume is itself a negative signal independent of anything about the content or the list.
The list composition then finishes the job. Any list that has not been rigorously maintained accumulates dead addresses, role accounts, and recycled spam traps — addresses that were once real, went dormant, and were reactivated by the provider specifically to catch senders mailing stale data. Sending to the full file on day one means hitting all of them at once, from a domain with no reputation buffer to absorb the damage.
Case study — how Signal & Send lost 25 points of open rate in one afternoon
Signal & Send is a six-person lifecycle agency. Their largest client at the time was a direct-to-consumer brand with a 180,000-contact list that had been on ActiveCampaign for four years, running at a 34% average open rate and generating roughly $70,000 a month in attributable email revenue. The client wanted to consolidate onto GoHighLevel so that email, SMS, CRM and their booking flow lived in one system per brand rather than four.
The migration plan was reasonable on paper. Export contacts, rebuild the six core flows, recreate the segments, point the sending domain at GHL, cut over on the first of the month. Everyone had done a platform migration before. Nobody on the team had ever had to think about warm-up, because in four years on ActiveCampaign the domain had simply always been warm.
The first campaign after cutover went to the full 180,000-contact file. It was a normal monthly promotion, the kind that usually returned 34% opens and around $18,000 in revenue. It returned 21%. The team noted it, assumed it was a subject-line miss, and moved on. The second campaign eight days later returned 14%. The third, a fortnight after cutover, returned 9% — and revenue for the month came in at $11,000 against a $70,000 baseline.
By then the diagnosis was straightforward and the seed-list data was ugly. Gmail placement, which represented 58% of the list, had fallen to 31% inbox with the remainder split between promotions and spam. Microsoft was worse at 22% inbox. Google Postmaster Tools showed domain reputation as "Low", and the spam complaint rate on the second send had touched 0.34% — well above the 0.10% threshold that Gmail treats as a warning line and more than three times the 0.10% they now formally require bulk senders to stay under.
Three specific decisions caused it. First, the full list was sent from a domain with no sending history whatsoever. Second, no segment was excluded — including roughly 47,000 contacts who had not opened anything in more than eighteen months, a cohort that contributed a disproportionate share of the bounces and complaints. Third, DMARC had been published at p=none with no monitoring of the aggregate reports, so an alignment problem on the first send went unnoticed for eleven days.
The recovery took eleven weeks. The old ActiveCampaign account, which had fortunately not been cancelled, was reactivated to carry revenue-critical sends while the GHL domain was rebuilt properly. A fresh subdomain was provisioned so the ramp started from clean ground rather than fighting the existing negative reputation. The list was cut to 108,000 by excluding everyone with no engagement in twelve months, and a re-permissioning campaign to the excluded 72,000 recovered 8,900 of them — a 12.4% confirmation rate.
The ramp itself started at 200 messages a day to the single most engaged segment and doubled every third day, with a full hold whenever the complaint rate exceeded 0.08% or the bounce rate exceeded 1.5%. Two holds happened, each costing four days. By week seven the domain was carrying 40,000 a day at a 29% open rate. By week eleven the full 108,000 went out in a day and returned 33.1% — effectively baseline, on a list that was 40% smaller.
The commercial outcome is the part worth sitting with. The client stayed, but the agency wrote off roughly $34,000 in fees across the recovery period and spent close to 200 unbilled hours. The lesson the team took away was not "warm up your domain." It was that the entire migration should have been sequenced backwards from the warm-up, because the warm-up is the longest-lead item and everything else can be built in parallel with it.
What DNS records do you need before sending a single message?
Three, and all three must be published and verified before the first message leaves the platform. SPF authorises which servers may send on behalf of your domain, DKIM cryptographically signs each message so receivers can verify it was not tampered with, and DMARC tells receivers what to do when either check fails while requiring the visible From domain to align with the authenticated one.
Since February 2024, Gmail and Yahoo have required all three from any sender exceeding roughly 5,000 messages per day to their users — see Google's email sender guidelines, which also set a spam-complaint ceiling of 0.3% in Postmaster Tools and require From-domain alignment with SPF or DKIM. Microsoft introduced equivalent requirements for high-volume senders in 2025. For a lifecycle agency, this is not an optimisation to schedule for later — it is the price of entry, and a client list of any meaningful size crosses those thresholds on the first campaign.
| Record | Full name | What it proves | Where it lives | Typical value shape |
|---|---|---|---|---|
| SPF | Sender Policy Framework | The sending server is authorised to send for this domain | TXT record at the sending domain root | v=spf1 include:<provider> ~all |
| DKIM | DomainKeys Identified Mail | The message was signed by the domain owner and not altered | TXT record at a selector subdomain, e.g. selector._domainkey | A long public key string, or a CNAME to the provider |
| DMARC | Domain-based Message Authentication, Reporting and Conformance | The From domain aligns with the authenticated domain, plus a failure policy | TXT record at _dmarc.yourdomain.com | v=DMARC1; p=quarantine; rua=mailto:[email protected] |
| Return-Path / bounce domain | Custom bounce address | Aligns the envelope sender with your domain for SPF alignment | CNAME at a subdomain | Provider-specified target |
| Tracking domain | Branded link tracking | Click and open tracking links resolve on your domain, not a shared one | CNAME at a subdomain | Provider-specified target |
Four practical details cause most of the failures we see.
The SPF record has a hard limit of ten DNS lookups. Every include: in the record counts, and nested includes count too. Clients who have accumulated Google Workspace, a helpdesk, an invoicing tool and two previous ESPs frequently exceed it, at which point SPF silently fails for everything. Audit and flatten before you add another include.
You may only have one SPF record per domain. Two TXT records both beginning v=spf1 is a permanent error, not a merge. If the client already has one, you edit it — you never add a second.
DMARC alignment is where migrations quietly break. It is not enough for SPF and DKIM to pass; the domain they pass for must match the domain in the visible From address. A message from [email protected] that authenticates against a provider's shared domain passes SPF but fails DMARC alignment. This is exactly what the tracking and bounce subdomain CNAMEs exist to fix.
Start DMARC at p=none with a reporting address, read the aggregate reports for two to three weeks, and only then move to p=quarantine and eventually p=reject. Publishing p=reject on day one on a domain you have not yet observed is a reliable way to have legitimate mail from the client's own systems silently discarded.
Should you use a subdomain or the client's main domain for sending?
Use a subdomain — something like mail.brand.com or news.brand.com — for bulk lifecycle sending in almost every case. It isolates marketing sending reputation from the corporate domain that carries invoices, support replies and the founder's personal correspondence.
The isolation cuts both ways and both directions matter. If a promotional campaign generates a complaint spike, that damage is contained to the marketing subdomain and the client's transactional and one-to-one mail continues to reach people. Equally, if something goes wrong on the corporate side — a compromised mailbox sending spam, for instance — your carefully warmed marketing subdomain is not automatically dragged down with it.
Subdomains also give you per-client and per-purpose granularity that a single domain cannot. A common structure is one subdomain for lifecycle marketing, a separate one for transactional messages such as receipts and password resets, and, for clients running genuinely distinct brands, a subdomain each. Each accumulates its own reputation.
The caveat is that subdomain reputation is not fully independent of the parent domain. Mailbox providers do consider the organisational domain, particularly for a brand-new subdomain with no history — which is one reason a subdomain of an established, well-behaved domain warms slightly faster than an entirely new domain purchased last week. It inherits a little goodwill, but not enough to skip the ramp.
One thing to avoid entirely: buying a fresh lookalike domain to send from. A domain registered three weeks ago with no organisational history is the single strongest cold-sender signal available, and it also invites the exact phishing heuristics you are trying to stay clear of.
How long should you warm up a new sending domain?
Four to six weeks to reach full volume on a list of 100,000 to 200,000 contacts. Smaller lists finish sooner because they hit their ceiling earlier — a 20,000-contact list is typically fully ramped in two to three weeks. Lists above 500,000 usually need eight weeks or more.
The principle is that you start small enough to be unremarkable and increase at a rate that looks like organic business growth rather than a sudden event. Roughly doubling every two to three days works well, held steady whenever the health metrics say to hold.
| Days | Daily volume | Send to | Watch for |
|---|---|---|---|
| 1–3 | 200 | Opened in last 30 days, most recent first | Bounce rate under 2%, any authentication failures |
| 4–6 | 500 | Opened in last 30 days | Complaint rate under 0.05%, open rate above 40% |
| 7–9 | 1,000 | Opened in last 30 days | Google Postmaster domain reputation registering at all |
| 10–12 | 2,500 | Opened in last 60 days | Seed-list inbox placement above 90% on Gmail |
| 13–15 | 5,000 | Opened in last 60 days | Complaint rate under 0.08%, spam placement trending down |
| 16–18 | 10,000 | Opened in last 90 days | Domain reputation at Medium or better |
| 19–21 | 20,000 | Opened in last 90 days | Bounce rate under 1%, Microsoft placement holding |
| 22–25 | 35,000 | Opened in last 180 days | Complaint rate holding under 0.10% at higher volume |
| 26–30 | 60,000 | Opened in last 180 days | Any provider-specific placement divergence |
| 31–38 | 100,000 | Full retained list | Reputation stable across a full week at volume |
| 39–42 | Full volume | Full retained list | Baseline open rate recovered |
Three rules govern how you actually use that table.
Engagement ordering is not optional. Every early batch goes to your most recently engaged contacts, most recent first. Those people open, click and reply at high rates, which is precisely the positive signal you are trying to bank while the domain is being evaluated. Sending the same 200 messages to a random slice of the list produces a fraction of the reputation benefit.
Consistency beats volume. A domain sending 1,000 a day every weekday looks healthier than one sending 5,000 on Monday and nothing until the following Thursday. Providers read regularity as legitimacy. Where possible, send on the same days at the same times.
Holds are part of the plan, not a failure of it. If bounce rate exceeds 2%, complaint rate exceeds 0.10%, or seed-list inbox placement drops below 85% on any major provider, you hold the current volume until the numbers recover — and if they do not recover within three sends, you step back a level. In the Signal & Send rebuild, two holds cost eight days total. That is a rounding error against an eleven-week failure.
How do you decide which contacts survive the migration?
By engagement recency, and more aggressively than feels comfortable. The default position is that anyone who has not opened or clicked in the last twelve months does not go into the new platform's active sending pool, and anyone dormant beyond eighteen months does not get migrated at all without a re-permissioning campaign first.
This is the part clients push back on hardest, and the pushback is understandable. Nobody enjoys being told that a 180,000-contact list they have spent four years building is functionally a 108,000-contact list. But every dormant address is pure downside during a warm-up. It cannot open, so it contributes no positive engagement signal. It can bounce, complain, or turn out to be a recycled spam trap.
| Last engagement | Share of a typical 4-year-old list | Migration action |
|---|---|---|
| 0–90 days | 18–25% | Migrate, use for warm-up batches 1–6 |
| 91–180 days | 12–18% | Migrate, introduce from batch 7 onward |
| 181–365 days | 15–20% | Migrate, suppress until domain fully warm |
| 366–540 days | 12–18% | Re-permission campaign from old platform, migrate confirmers only |
| 540+ days | 25–40% | Do not migrate; re-permission optionally, expect 5–15% recovery |
Alongside recency, run four mechanical hygiene passes on the export.
Syntax and formatting validation removes malformed addresses, obvious typos in major domains, and entries with stray whitespace or encoding artefacts — usually 0.5% to 2% of a list that has been through multiple platform migrations.
Role-account removal strips generic addresses such as info@, sales@, admin@ and support@. These are often distribution lists read by several people, and they generate complaints at several times the rate of individual addresses.
Known-bounce and unsubscribe carry-over is the one people forget. Your old platform's suppression list is the single most valuable file in the export, and it does not always come across automatically. Import it as an explicit suppression before importing contacts. Emailing someone who unsubscribed two years ago is both a compliance problem and a guaranteed complaint.
Third-party verification against a validation service is worth the cost on any list older than eighteen months. Expect 3% to 12% invalid on a poorly maintained list. At roughly $0.004 per address, verifying 180,000 contacts costs around $720 — trivially cheap against the alternative.
Run re-permissioning from the old platform, not the new one. That is the entire point. The old domain is warm and can absorb the low engagement and elevated complaint rate that a re-permission campaign inevitably produces. Sending it from the cold new domain would be the worst possible first campaign.
How does A2P 10DLC registration affect your SMS launch timeline?
It adds three to fifteen business days before you can legally send a single US SMS message, and it is the item most likely to delay a launch because agencies routinely treat it as a form to fill in rather than a lead-time dependency.
A2P 10DLC — application-to-person messaging over ten-digit long codes — is the framework US carriers use to vet business SMS traffic, administered by The Campaign Registry. Every business sending automated messages to US mobile numbers from a standard local number must register the brand and the specific campaign; HighLevel documents the in-platform flow in A2P Standard Brand Registration for 10DLC. Unregistered traffic is heavily filtered or blocked outright, and the filtering is silent from the sender's side.
| Stage | What it involves | Typical duration |
|---|---|---|
| Data collection | Legal entity name, EIN, address, website, authorised contact | 1–5 days, client-dependent |
| Brand registration | Registry verifies the entity against tax records | 1–3 business days |
| Campaign registration | Use case, sample messages, opt-in description and evidence | 2–10 business days |
| Carrier provisioning | Approved campaign attached to numbers across carriers | 1–3 business days |
| Number warm-up | Gradual volume increase on newly provisioned numbers | 1–2 weeks |
Brand rejections are the main source of delay and are almost always a data-quality problem. The legal entity name must match the tax registry exactly — "Brand Co" fails where "Brand Company LLC" succeeds. The EIN must be correct to the digit. The address must match the registered address, not the operating one. Get these at onboarding, in writing, from someone in the client's finance function rather than from marketing.
Campaign rejections come from vague use-case descriptions or weak consent evidence. Registries want to see how consent is collected, so provide the actual opt-in language, a screenshot of the form, and sample messages that include the brand name and clear opt-out instructions. A sample message reading "Hi {{first_name}}, your order shipped! Reply STOP to opt out" clears review far more easily than a generic description of intent.
Throughput matters after approval. A2P assigns a trust score that determines your messages-per-second rate. A newly registered standard brand may be limited well below what a high-volume campaign needs, so a client planning a 50,000-message launch send should know in advance whether that will take twenty minutes or six hours.
Practically, this means A2P registration is a week-one onboarding task, filed the same day the contract is signed, in parallel with everything else. It has nothing to do with how the flows are built and everything to do with whether they can run.
How do you rebuild ESP segmentation inside GoHighLevel?
By translating segments into GoHighLevel's three native primitives — tags, custom fields, and smart lists — rather than trying to find a one-to-one equivalent for the old platform's segment builder. The mapping is straightforward once you accept that it is a translation and not a copy.
This is where agencies coming from Klaviyo feel the most friction, because Klaviyo's segment engine evaluates conditions live against event data, while GoHighLevel's model leans on tags and fields set by workflows. The distinction matters: a Klaviyo segment recalculates itself, while a GHL tag stays applied until something removes it.
| Old platform concept | GoHighLevel equivalent | Notes |
|---|---|---|
| Static list | Tag | One tag per former list, applied at import |
| Dynamic segment (attribute-based) | Smart list with filters | Recalculates on view, closest true equivalent |
| Dynamic segment (behaviour-based) | Workflow that applies and removes a tag | Requires explicit removal logic |
| Custom property | Custom field | Map types deliberately — dates as dates, not text |
| Profile score / engagement tier | Custom field updated by workflow | Recalculate on a schedule |
| Suppression list | Do-not-contact / suppression import | Import before contacts, never after |
Four practices keep the rebuild from becoming unmanageable.
Adopt a tag naming convention before you create the first tag. Something like src-, beh-, life- and sup- prefixes for source, behaviour, lifecycle stage and suppression keeps a client account navigable at 200 tags. Without one, you get 400 tags with overlapping meanings inside a year, and no one can safely delete any of them.
Every behavioural tag needs removal logic. This is the single most common GHL segmentation bug. A workflow applies beh-cart-abandoned and nothing ever removes it, so six months later a large share of the list carries a tag describing something they did once in March. Every apply action needs a matching remove action on the completing event.
Map engagement recency explicitly. Because the entire warm-up depends on sending in engagement order, you need last-open and last-click dates as usable fields in GHL from day one. Import them from the old platform's export rather than starting from zero, and maintain them with a workflow thereafter.
Rebuild the segments you actually use. A four-year-old ESP account typically contains 60 to 120 saved segments, of which maybe 15 have been used in the last year. Audit send history, rebuild the live ones, and archive the rest. Migrating all 120 guarantees that nobody trusts any of them.
How do you build cross-channel email and SMS flows that respect both channels?
By treating email and SMS as different media with different tolerances rather than as two delivery options for the same message. The single most common cross-channel mistake is sending the same content twice — the same offer, minutes apart, in both channels — which reads as pressure and drives opt-outs in both.
The design principle that works is channel roles. Email carries detail, imagery, multiple links and anything requiring consideration. SMS carries urgency, brevity and time-sensitivity — a confirmation, a reminder, a closing window. When a message has a genuine job in only one channel, it goes in only that channel.
A worked example, a four-day abandoned-cart sequence:
- Hour 1 — Email. Full product imagery, the abandoned items, a single clear return link. No discount.
- Hour 20 — SMS, only if the email is unopened after 18 hours. One line, under 160 characters, direct link. This is where SMS earns its cost — reaching people email did not.
- Day 2, hour 44 — Email. Social proof, reviews, shipping and returns reassurance. Still no discount.
- Day 3, hour 68 — SMS, only if no email engagement across either previous send. Time-bound incentive with an explicit expiry.
- Day 4, hour 92 — Email. Final reminder, incentive restated, expiry visible.
Three rules make sequences like this behave.
Global frequency capping sits above every individual flow. Set a hard ceiling — commonly four to six marketing emails and two to three marketing SMS per contact per week — enforced across all flows, not per flow. Without it, a contact who qualifies for a browse-abandon flow, a win-back and a promotional campaign in the same week receives eleven messages and unsubscribes from all of them.
Quiet hours are non-negotiable for SMS. No promotional messages before 9am or after 8pm in the recipient's local time zone, which requires storing a time zone on the contact record and respecting it in every SMS-sending step. This is both a compliance matter in most jurisdictions and a basic courtesy that shows up directly in opt-out rates.
Suppress across channels on conversion. When someone completes the desired action, they exit every flow driving toward it, in both channels simultaneously. A customer who buys and then receives the day-3 discount SMS for the item they just bought at full price is a support ticket and a refund request.
How do you handle unsubscribes and opt-outs across two channels?
Separately in mechanism, jointly in respect. Email unsubscribes and SMS opt-outs are governed by different rules and use different keywords, but the operating principle is that a contact who has clearly signalled they want less contact should never be surprised to hear from you on the other channel.
For email, one-click unsubscribe via the List-Unsubscribe header has been a Gmail and Yahoo requirement for bulk senders since February 2024, and the request must be processed within two days. Practically this means the header must be present on every marketing send and the visible unsubscribe link must work in one click — no login, no preference-centre gauntlet, no confirmation page that a distracted person will abandon halfway through, leaving them still subscribed and now annoyed enough to hit the spam button instead.
That last point is the whole argument for making unsubscribing easy. A spam complaint damages your sending reputation. An unsubscribe does not. Anything that makes unsubscribing harder converts harmless departures into reputation damage, and Gmail's 0.10% complaint-rate threshold leaves very little room for that trade.
For SMS, carriers require automatic handling of STOP, STOPALL, UNSUBSCRIBE, CANCEL, END and QUIT, plus HELP returning contact information. GoHighLevel handles the standard keywords natively, but two things need explicit attention. First, confirm the handling is active on every number and every campaign rather than assuming it. Second, decide what happens to the contact record — an SMS opt-out should set a clear field or tag that every SMS-sending workflow checks, so the state is visible to anyone looking at the record rather than buried in a channel setting.
The cross-channel question is a judgement call worth making deliberately with each client. A hard rule that any opt-out on either channel suppresses both is the safest and cleanest, and it is what we default to. A softer rule treats them independently but suppresses the other channel after two opt-outs or any complaint. What is not acceptable is treating an SMS STOP as an invitation to increase email frequency, which some automated re-engagement logic does accidentally.
A preference centre is the constructive middle path and consistently outperforms a binary choice. Offering "fewer emails", "only product news", or "pause for 60 days" alongside full unsubscribe typically retains 20% to 35% of people who arrived intending to leave entirely. The pause option in particular is under-used and remarkably effective.
How do you monitor inbox placement instead of guessing?
With seed lists, Google Postmaster Tools, and DMARC aggregate reports — three independent sources that between them tell you where messages actually landed, what the major providers think of your domain, and whether authentication is working. Open rates alone will not tell you, and since Apple Mail Privacy Protection began pre-fetching images they will actively mislead you.
Seed lists are the direct measurement. You maintain test accounts across Gmail, Outlook, Yahoo, Apple iCloud and a few smaller providers, include them in every send, and check where each message landed. This is the only method that distinguishes inbox from promotions tab from spam, per provider, within minutes of a send. During a warm-up, check them after every single send without exception.
Google Postmaster Tools gives you Gmail's own view — domain reputation, IP reputation, spam complaint rate, authentication pass rates and delivery errors. It requires verifying the sending domain and only reports meaningfully above a few hundred messages a day to Gmail users, which the ramp reaches within about a week. Domain reputation moving from "Low" toward "Medium" and then "High" is the clearest single signal that a warm-up is working.
DMARC aggregate reports arrive as XML from every receiving provider, summarising authentication results for mail claiming to be from your domain. They are unreadable raw and worth routing through a parsing service. They catch the alignment failures that no other tool surfaces, and they are how you learn that a client's invoicing system has been failing DMARC for a month.
The thresholds worth alerting on:
- Spam complaint rate above 0.10% — Gmail's stated limit; investigate immediately at 0.08%.
- Hard bounce rate above 2% on any send — indicates list quality problems.
- Seed-list inbox placement below 85% on any major provider — hold the ramp.
- Google Postmaster domain reputation dropping a tier — hold and diagnose before the next send.
- DKIM or SPF pass rate below 98% — an authentication or configuration fault, not a content problem.
The reporting habit that keeps clients calm is showing them this data monthly, in plain language, whether or not anything is wrong. An agency that reports inbox placement by provider alongside revenue is an agency that is very hard to replace, because the client can see work being done that they could not do themselves and would not know how to evaluate elsewhere.
How do you prove revenue per send to clients?
By instrumenting the full chain from send to revenue and reporting it per campaign, per flow and per channel. The number that matters is revenue per message sent, because it is the only figure that puts a $400 SMS campaign and a $0 email campaign on the same footing and lets you argue for channel mix on evidence rather than preference.
The chain has five links, and each needs to be measured: messages sent, messages delivered, messages opened or read, clicks, and attributed conversions with revenue value. Break at any link and the number at the end is a guess.
| Metric | What it tells you | Healthy range for lifecycle email |
|---|---|---|
| Delivery rate | Accepted by receiving server | Above 98% |
| Inbox placement rate | Reached inbox rather than spam | Above 90% |
| Open rate | Engagement, inflated by privacy pre-fetch | 20–40% depending on segment |
| Click-through rate | Genuine interest, more reliable than opens | 2–5% of delivered |
| Conversion rate | Completed the desired action | 0.5–3% of delivered |
| Revenue per email sent | The commercial bottom line | $0.05–$0.50 typical, higher for retention flows |
| Revenue per SMS sent | Same, against a real per-message cost | Must clear roughly $0.01–$0.03 send cost |
Three things make this reporting trustworthy rather than decorative.
Consistent UTM tagging on every link in every message, applied by convention rather than by hand. Campaign, channel, flow name and message position, standardised across clients. Inconsistent tagging is the reason most agency attribution reports cannot be compared month to month.
An honest attribution window, agreed with the client in advance. Seven days for email click-through and 24 to 48 hours for SMS are reasonable defaults. What matters more than the specific number is that it never changes, because a window that quietly widens produces improving numbers that mean nothing.
Flow-level revenue separated from campaign-level revenue. Automated lifecycle flows typically generate 25% to 40% of total email revenue from a small fraction of total volume, and their revenue-per-send is often five to ten times that of broadcast campaigns. Showing that split is the single most effective argument for the retainer, because it demonstrates that the always-on infrastructure you maintain is out-earning the campaigns everyone notices.
For SMS specifically, always show revenue net of send cost. At roughly $0.01 to $0.03 per message including carrier fees, a 50,000-message campaign costs $500 to $1,500 before anyone opens anything. A campaign returning $4,200 gross on a $900 spend is a different conversation from one returning $4,200 with no cost shown, and clients respect the agency that volunteers the cost line.
What does a correctly sequenced GoHighLevel migration look like?
It runs eight to twelve weeks, it is sequenced backwards from the warm-up ramp because that is the longest-lead item, and it keeps the old platform live for most of that period. Almost every disaster we have been called in to fix was a migration compressed into two or three weeks because a launch date was chosen before anyone asked how long the warm-up would take.
Week 1 — Foundations, all in parallel. Provision the sending subdomain and publish SPF, DKIM and DMARC at p=none with reporting. File A2P 10DLC brand and campaign registration. Export contacts, engagement history and the suppression list from the old platform. Audit the client's existing SPF record for the ten-lookup limit. Nothing sends this week.
Week 2 — Hygiene and structure. Run verification and role-account removal on the export. Segment by engagement recency and agree the retention cut-off with the client in writing. Import the suppression list first, then contacts with engagement dates as custom fields. Build the tag taxonomy. Launch the re-permissioning campaign from the old platform.
Weeks 3–4 — Build and begin the ramp. Start the warm-up at 200 a day to the most engaged segment while the flows are being built. Rebuild the live segments as smart lists. Construct the core lifecycle flows with cross-channel logic, frequency caps and quiet hours. Confirm A2P approval and warm the SMS numbers.
Weeks 5–8 — Ramp and parallel run. Continue doubling the ramp every two to three days, holding whenever the metrics require it. The old platform still carries the bulk of revenue-critical sending. Move segments over as the ramp allows, most engaged first. Check seed lists after every send. Watch Postmaster reputation move from Low to Medium to High. Move DMARC to p=quarantine once aggregate reports are clean.
Weeks 9–12 — Cutover and stabilise. Once the new domain handles comparable volume at comparable placement, cut over fully. Keep the old platform in read-only for another 30 days. Establish monthly deliverability reporting. Move DMARC to p=reject if the reports support it.
The economics of doing it this way are not close. A properly sequenced migration for a list of this size costs around $1,000 in setup plus a retainer between $400 and $1,200 a month depending on client volume and channel mix. Signal & Send's compressed migration cost them $34,000 in written-off fees, roughly 200 unbilled hours, and a client relationship that survived on goodwill rather than performance for a quarter.
What should you do next?
If you are an email or SMS agency with a GoHighLevel migration on the calendar, work backwards from the warm-up. Take the client's list size, find it on the ramp table, count the weeks, and set the cutover date from there. If the resulting date is later than the one already promised, that conversation is far easier to have now than in week three of a collapse.
Then check the three things that cause the most damage and cost the least to verify. Is the client's existing SPF record under the ten-lookup limit? Is A2P 10DLC filed, or merely intended? Do you know the last-engagement date for every contact in the export, and have you agreed with the client which of them are not coming across?
The uncomfortable truth of this work is that the skill that wins the client — lifecycle strategy, segmentation, copy that converts — is not the skill that keeps them. What keeps them is that the messages arrive. That is infrastructure work, it is unglamorous, it has a lead time you cannot compress, and it is the thing clients only notice when it fails.
GHL Spark builds this layer for agencies who would rather spend their hours on strategy than on DNS records and registry paperwork — dedicated sending domain with full authentication, a staged warm-up run and monitored on your behalf, A2P 10DLC filed at onboarding, list hygiene and consent mapping, segmentation rebuilt as tags and smart lists, cross-channel flows with frequency capping and quiet hours, and per-client deliverability and revenue-per-send reporting you can put straight in front of a client. Setup is around $1,000, with ongoing management between $400 and $1,200 a month. The point is not that you could not do it yourself. It is that the warm-up runs for six weeks either way, and those are six weeks you could spend selling the next account.
Sources and further reading
Requirements in this area are set by mailbox providers, carriers and regulators, and they move. Check the primary sources before you commit a client to a sending plan:
- Google: email sender guidelines — SPF/DKIM/DMARC, the 0.3% spam-rate ceiling and domain alignment for bulk senders.
- Google: sender guidelines FAQ — how the 5,000-per-day threshold is applied.
- FTC: CAN-SPAM Act compliance guide for business — the legal floor for commercial email, including working unsubscribe and accurate headers. There is no B2B exemption.
- CTIA Messaging Principles and Best Practices — the consent and content standard for SMS.
- The Campaign Registry — A2P 10DLC Brand and Campaign registration.
Frequently asked questions
How long should you warm up a new sending domain?
What happens if you migrate a list and send to everyone immediately?
What are SPF, DKIM and DMARC and do you need all three?
How long does A2P 10DLC registration take for a new client?
Should you re-permission a list before migrating it to GoHighLevel?
Can you keep your old ESP running during a GoHighLevel migration?
How do you monitor inbox placement rather than just open rates?
How do you isolate sending reputation between different clients?
About the author

Farhad
Founder, GHL Spark
Farhad is the founder of GHL Spark, where he builds and white-labels GoHighLevel SaaS platforms for agencies and SaaS operators. He writes about the parts of GoHighLevel that actually break in production — A2P registration, onboarding, support load and automation.