Migrating messaging providers without duplicates or missing statuses
A controlled SMS and notification migration using a canonical status model, stable identifiers, shadow validation, gradual traffic shifts, and rollback.

Contents
Changing a messaging provider looks like replacing an endpoint and credential until duplicate SMS, missing delivery reports, and incompatible error meanings appear. A safe migration separates business-event intake, routing, submission, and outcome tracking. Traffic can then move gradually and return without changing every calling system.
Document the current contract
Inventory message types, senders, templates, countries, encodings, limits, and delivery windows. Record the synchronous API response, intermediate events, and final delivery reports separately. Two providers may use the same status word for different points in the lifecycle.
Your canonical model should not copy one vendor’s vocabulary. States such as queued, accepted, delivered, failed, expired, and unknown are usually enough, while the original provider code remains available for diagnosis. See our guide to delivery metrics and DLRs for the measurement model.
Keep the business identifier stable
Assign an immutable internal ID before selecting a route. Give each provider attempt its own ID linked to that business message. This distinguishes transport retries from a genuinely new communication.
Do not base idempotency on the provider message ID alone: it appears after acceptance and changes when the route changes. The audit record should connect the business event, attempt, route, API response, and every callback.
Validate the new adapter without duplicating delivery
Begin with contract tests and authorised test recipients. Verify encoding, segmentation, sender identity, timeouts, rate limits, callback signatures, status ordering, and webhook redelivery.
Normalise status ingestion around the controls in our reliable DLR webhook guide: signatures, replay protection, idempotency, and out-of-order events should behave consistently for both providers.
Shadow mode must not submit a second customer message. Pass a prepared request through the new adapter’s validation and transformation path without final submission, or use a dedicated provider sandbox. The goal is to compare routing decisions and payload construction, not to send twice.
Shift traffic in measurable stages
A practical sequence is:
- operational and test recipients;
- one non-critical notification type;
- a small production percentage;
- a selected region or sender;
- primary traffic after a complete observation window.
At each step compare acceptance, delivery within target, percentile latency, error distribution, segment count, and business conversion. A mean hides the long tail; p95 and p99 are more useful for migration gates.
Do not blindly resend an unknown result
A timed-out request may still have been accepted. Sending immediately through the second provider can create a duplicate. Query status or rely on a stable idempotency key, then reconcile delayed outcomes. Our SMS route failover guide explains controlled cascade rules.
Roll back routing, not code history
Keep the old adapter operational for an agreed overlap period. A rollback moves only new events; messages already accepted by the new provider must continue receiving callbacks through its path. Otherwise, their final states disappear.
After the last traffic shift, reconcile both providers for at least the maximum message TTL. Then revoke old credentials, close callbacks, update operating documentation, and retain baseline metrics. Migration is complete when no unfinished message depends on the old path, not when the dashboard first reaches 100% new-provider traffic.


