Skip to main content
SwiftCase
PlatformForward-deployedSwitchboardFeaturesSolutionsCase StudiesFree ToolsPricingAbout
Book a Demo
SwiftCase

Workflow automation for UK service businesses. Created in the UK.

A Livepoint Solution

Platform

  • Platform Overview
  • Workflow Engine
  • Case Management
  • CRM
  • Document Generation
  • Data Model
  • Integrations
  • Analytics

Switchboard

  • Switchboard Overview
  • Voice AI
  • Chat
  • Email
  • SMS
  • WhatsApp

Features

  • All Features
  • Claims Operations
  • High-Volume Operations
  • Multi-Party Collaboration
  • Contract Renewals
  • Compliance & Audit
  • Pricing
  • Case Studies
  • Customers
  • Why SwiftCase

Company

  • About
  • Our Team
  • Adam Sykes
  • Nik Ellis
  • Implementation
  • 30-Day Pilot
  • Operations Pressure Map
  • For Your Role
  • Peer Clusters
  • Engineering
  • Careers
  • Partners
  • Press
  • Research
  • Tech Radar
  • Blog
  • Contact
  • SwiftCase Signal

Resources

  • Use Cases
  • Software
  • ROI Calculator
  • Pressure Diagnostic
  • Pilot Scope Estimator
  • Board Case Builder
  • Free Tools
  • Guides & Templates
  • FAQ
  • Compare
  • Glossary
  • Best Practices
  • Changelog
  • Documentation
  • Help Centre

Legal

  • Privacy
  • Terms
  • Cookies
  • Accessibility

Stay in the loop

Cyber Essentials CertifiedGDPR CompliantUK Data Centres

© 2026 SwiftCase. All rights reserved.

Back to Blog
Engineering

What actually changes when you move SMS carrier

Swapping the API call takes an afternoon. The work is in the status vocabulary your workflows already depend on, and in what you believe about a message you cannot confirm.

Dr. Adam Sykes

Dr. Adam Sykes

Founder & CEO

August 6, 2026
6 min read
Contents
  • Your workflows already believe things about status codes
  • Deciding whether the endpoint is real
  • The question that took the longest: did that message cost us money?
  • What we deliberately left alone
  • The bit that catches everyone
  • If you're planning one of these

We moved SMS delivery to Webex Interact this summer. The part everyone imagines is the part that took an afternoon: authenticate, POST a message, read the response.

The rest of it took a fortnight, and none of that fortnight was spent on sending messages. It went on three questions that only turn up once you're carrying somebody else's operational history.

Your workflows already believe things about status codes

SwiftCase has been sending SMS for years. In that time customers have built automation on top of delivery status: chase again when a message goes undelivered, move the task on when it lands, hold the status while it's still in flight. Those rules exist in hundreds of workflow configurations we don't control and can't see.

The old carrier reported status as single-letter codes. The new one reports words.

There's a tempting version of this migration where you adopt the new vocabulary, because it's clearer, and update the documentation. That version breaks every automation rule any customer ever wrote against the old codes, silently, in production, on a channel where failure looks like a customer not being told something.

So the integration translates at the boundary. Webex reports submitted, delivered and failed, and each maps onto the code that workflows already understand: pending, delivered, undelivered. Nothing downstream of the mapping knows the carrier changed.

The interesting case is a status we don't recognise. A carrier is free to add one, and it will eventually. An unmapped status returns 204 and changes nothing, so a new code from Webex leaves the message in whatever state it was already in. Guessing would be worse, and rejecting the webhook would make the carrier retry something we're never going to accept.

Deciding whether the endpoint is real

Delivery receipts arrive as webhooks, which means an endpoint on your side that anyone can post to.

Webex signs its events with HMAC, so verification is standard. Two details were less obvious.

Before Webex will save a webhook at all, it verifies the endpoint exists with a GET or HEAD request. That probe is unsigned, because there's nothing to sign. So the endpoint answers non-POST requests with a plain 200 and does no work, and treats POST as the only method that can change anything.

The second detail is what to do with a POST that fails verification. Rejecting it is obvious. What matters more is recording why, because a signature that fails is either an attack or your own configuration being wrong, and those look identical from the outside until somebody looks. We log enough to tell them apart. In practice it has always been the second thing, and having the diagnostic turned a long afternoon into a short one.

The question that took the longest: did that message cost us money?

Customers buy SMS credits. A message costs a credit. Straightforward until you consider what happens when you send a request and don't get a clear answer back.

There are three cases, and most systems only implement two.

The carrier accepts the message. Consume the credit.

The carrier definitively rejects it. Release the credit back, because nothing was sent.

The carrier times out, returns a 500, or the connection drops mid-request. Now you genuinely do not know. The message may have gone. It may not.

The comment in our repository says it plainly: unknown outcomes deliberately remain reserved.

That's the conservative direction and it's the correct one. If you release the credit on an uncertain send and the message did go, you have given away a credit and your balance now overstates what the customer has. Do that at volume and the number on the screen becomes fiction. Keeping it reserved means the worst case is a customer temporarily holding fewer credits than they should, which is visible, complainable, and fixable.

Then somebody has to fix it. A scheduled job sweeps reservations that have sat unknown past their expiry and marks them for review, so they become a short list a human works through rather than a slow leak nobody notices. Each one is locked while it's examined, because two processes reconciling the same reservation is exactly the bug you don't want in credit accounting.

What we deliberately left alone

Two things stayed where they were, and both were arguments at the time.

Scheduling stayed in SwiftCase. Webex can schedule sends. Using that would have meant a message living in two places, with cancellation, editing and audit split across a boundary we don't control. Scheduled messages stay in the platform until the moment they go, which keeps cancellation instant and keeps the audit trail in one system. It also means changing carrier again touches less.

Cost checks run locally. The carrier has a test endpoint that will price a message for you. Calling it on every send makes your ability to quote a cost depend on their availability, and turns a local calculation into a network round trip in the hot path. We price from a local table and reconcile against invoices.

Both decisions follow the same rule: use the carrier for the thing only the carrier can do, which is putting a message on a network. Everything else is yours and should stay that way.

The bit that catches everyone

One more, because it cost us a morning. A scheduled batch that fails validation on a single message used to take down the dispatcher processing that batch. One bad phone number, and every message queued behind it stopped.

A validation failure now fails that message and lets the rest continue. It's the sort of thing that never shows up in testing, because in testing your data is clean, and shows up immediately in production, because in production somebody has typed a phone number with a space in it.

If you're planning one of these

Write down what your system currently believes about delivery status before you look at the new carrier's documentation. That list is the actual specification, and it will be longer than you expect.

Decide your uncertain-outcome policy explicitly, and write the comment explaining it, because in six months the conservative choice will look like a bug to whoever reads it next.

And keep the boundary narrow. The less of your operation lives on the other side of an integration, the less a migration costs, and there will be another migration.


Further reading:

  • Documents and email: templates, tags and sending from a case
  • Changelog: the SMS work as it shipped, month by month
  • Integrations: how SwiftCase connects to the systems around it
  • Automated events: the SMS event and its timing controls

Related Articles

Engineering

Why we took the percentages off the claims card

August 17, 20267 min read
Engineering

Letterheads and logos that survive the template

August 12, 20266 min read
Engineering

Voice reliability: the settings you change after go-live

July 7, 20267 min read

Get automation insights delivered

Join operations leaders who get weekly insights on workflow automation and AI.

About the Author

Dr. Adam Sykes
Dr. Adam Sykes

Founder & CEO

Founder & CEO of SwiftCase. PhD in Computational Chemistry. 35+ years programming experience.

View all articles by Adam →

Related Free Tools

Workflow Mapper

Draw your business process visually and export a professional PDF.

Try free

SLA Template Builder

Build and download a professional Service Level Agreement.

Try free

Meeting Cost Calculator

See the true cost of your meetings based on attendees and salary.

Try free

11.8M+ cases processed

How we build SwiftCase

A look behind the curtain at the engineering decisions, tools, and culture that power our platform.

Meet the Engineering Team
View Careers