Back to Blog
API IntelligenceSMSIncidents

Your SMS Provider Says “Everything Is Fine”… But Your Users Aren’t Getting Messages

OutboundIQ TeamOutboundIQ Team
3 min read
Your SMS Provider Says “Everything Is Fine”… But Your Users Aren’t Getting Messages

It usually starts like this.

One user says they didn’t get their OTP.
You resend. It works.

Then it happens again.
And again.

Soon, people can’t log in.

You check everything on your end:

  • Your queue is working
  • Your API is responding
  • Your logs look clean

Then you check your SMS provider.

Status: All systems operational

So… what’s going on?

The problem nobody sees early

Most outages don’t happen all at once.

They start slowly:

  • Messages take longer to deliver
  • Some requests fail
  • Retries increase

Nothing is fully broken yet.
But your users are already feeling it.

Why this is hard to catch

Most teams only check:

  • “Is the provider up?”
  • “Did my request go through?”

But that’s not enough.

A provider can be up… but performing badly — and that’s where the real problem is.

What you actually need

Instead of asking:

“Is my provider working?”

You should be asking:

“Is my provider still good enough for my users right now?”

Using OutboundIQ (Laravel example)

With OutboundIQ, you can check your provider before sending messages.

providerStatus() returns an array (or null if the call fails). Use the decision block to see whether the provider is considered usable, and metrics for latency and success rate — the same shape as in the providerStatus() docs.

Here is a simple pattern (replace 'twilio' with the provider slug you configured in OutboundIQ):

use OutboundIQ\Laravel\Facades\OutboundIQ;

$status = OutboundIQ::providerStatus('twilio');

if ($status && $status['decision']['usable']) {
    // Send SMS normally
    Sms::send($phone, $message);
} else {
    // Switch to backup provider
    SmsBackup::send($phone, $message);
}

What’s happening here?

Before you send anything, you check:

  • Is this provider considered usable right now?
  • Is it slowing down or failing more than usual (see metrics)?

If the decision says to avoid or wait — or usable is false — you failover instead of hoping the status page wording matches your integration.

Optional: log when you failover

If you want observability when you skip the primary provider:

use Illuminate\Support\Facades\Log;
use OutboundIQ\Laravel\Facades\OutboundIQ;

$status = OutboundIQ::providerStatus('twilio');

if (!$status || !$status['decision']['usable']) {
    Log::warning('SMS provider not usable; using backup', [
        'avg_latency_ms' => $status ? ($status['metrics']['avg_latency_ms'] ?? null) : null,
        'success_rate' => $status ? ($status['metrics']['success_rate'] ?? null) : null,
        'action' => $status ? ($status['decision']['action'] ?? null) : null,
    ]);
    SmsBackup::send($phone, $message);
    return;
}

Sms::send($phone, $message);

Why this matters

Without this: you keep sending to a struggling provider, OTPs don’t arrive, logins fail, and support tickets pile up.

With this: you catch degradation earlier, switch before users feel it, and keep the path working.

The simple truth

Your provider can be “up” and still be failing your users.

The difference is whether you see it early — or only after the damage is done.

Take the next step

Ready to monitor your APIs?

Get started with OutboundIQ in under 5 minutes.

Start Free Trial