Changing an SMS provider in a CRM is a data migration as much as a transport change. A message can leave the new provider successfully while the CRM shows the wrong conversation, misses a delivery failure, or sends again after an opt-out. Before switching a real number, run a small test with a dedicated number and consented test contacts. Keep the old path available until every critical case has an expected result and an event log to prove it.
I work with Phone Clover, an early-access HighLevel and Telnyx integration. This is the acceptance checklist I would use for any CRM and SMS-provider connection; it is not a claim that every Phone Clover path below is production-ready.
Set up the test
Use one sending number, two test contacts, and a third number that cannot receive SMS. Record the provider message ID, CRM contact ID, timestamp, sending number, recipient, and final status for each case. Use synthetic text, not real customer information. Disable campaigns and bulk sends while you test. Confirm the sending number and business messaging registration are eligible before attempting outbound traffic.
| # | Test | Expected evidence |
|---|---|---|
| 1 | Send a one-to-one text from contact A | One provider message ID and one CRM conversation entry |
| 2 | Reply from contact A | Reply appears on A's thread, with the correct number and timestamp |
| 3 | Send to contact B | No event or content appears on A's thread |
| 4 | Send from a second assigned number | The CRM records the number actually used |
| 5 | Send to a landline or invalid destination | A visible failure reason, not a false delivered status |
| 6 | Simulate a carrier rejection | Failure is logged and any retry follows an explicit policy |
| 7 | Deliver the same webhook twice | One CRM event, not two messages |
| 8 | Deliver status webhooks out of order | A late sent event cannot replace a terminal failed or delivered status |
| 9 | Send a STOP reply | The contact is marked opted out and future sends are blocked |
| 10 | Try a send after opt-out | It is rejected before reaching the provider |
| 11 | Disconnect the provider briefly | The operator sees a recoverable error and knows whether retry is safe |
| 12 | Reconnect or roll back | Historical threads remain readable and new messages take the intended path |
Treat webhooks as events, not commands to blindly replay
Delivery callbacks can be retried or arrive after another state change. Persist an event key, ignore duplicates, and keep terminal states from moving backward. The exact keys and status names differ by provider, but the rule can be tested with a tiny replay script:
for event in shuffled_and_duplicated(test_events): if already_processed(event.id): continue message = find_by_provider_message_id(event.message_id) if message is missing: quarantine(event) continue if transition_allowed(message.status, event.status): apply_status(message, event.status) mark_processed(event.id) The quarantine path matters. A status callback that cannot be tied to a known message needs investigation; silently attaching it to a contact by phone number can corrupt a conversation when numbers are shared or reassigned.
Make opt-out and retry tests explicit
An automatic retry can help with a transient failure, but it must never override an opt-out, a quiet-hours hold, or a permanent rejection. Write down which failure codes are retryable, the maximum retry count, and whether a different sending number is ever allowed. Test the policy with the feature off before enabling it. The CRM should expose the reason a send failed so a rep does not unknowingly resend the same message.
Decide what counts as a pass
For each case, save the CRM view and the provider event log. A pass means the two agree on recipient, number, content, status, and time, and no extra message was sent. If they disagree, keep the case open even if the test handset received the text. Run the full set once per subaccount or client configuration; a successful pilot does not prove every routing setup.
Our Phone Clover feature-status page is an example of publishing the boundary between available, early-access, and unfinished messaging paths. At the time of writing, its HighLevel Conversations texting runs in a pilot and approved installs, while workflow and bulk texting are not ready. Whatever provider you choose, test only the paths it actually supports and keep a documented fallback for the rest.