---
title: "Choose a provider"
description: "Pick an SMS provider for SMS SDK: a quick decision table, support status, capability matrix, and sender types for Twilio, Telnyx, Plivo, Vonage, Bandwidth, and Sinch."
sidebar:
  label: "Overview"
---

Every adapter uses the same `send()` call and the same webhook events, so you can pick by features and switch later. Start with the provider where your numbers and sender registrations already live.

## Which one should I pick?

| Your situation | Use |
| --- | --- |
| You already have an account and registered senders somewhere | That provider |
| You need MMS | [Twilio](/providers/twilio), [Telnyx](/providers/telnyx), or [Plivo](/providers/plivo) |
| You need short codes | Twilio, Telnyx, Plivo, [Bandwidth](/providers/bandwidth), or [Sinch](/providers/sinch) |
| You need scheduled sends from any sender | Telnyx or Sinch |
| You need scheduling from a Twilio Messaging Service | Twilio |
| You want fallback to trigger on exactly the right errors | Twilio or Telnyx. Their error codes are fully documented. |
| You use the Vonage Messages API | [Vonage](/providers/vonage), with JWT auth if you need webhooks |
| You want a second provider for fallback | Any two. Put a Supported one first if you mix statuses. See [Fallback and retries](/sending/fallback-and-retries). |

## Support status

| Provider | API | Status | Main limits |
| --- | --- | --- | --- |
| [Twilio](/providers/twilio) | Programmable Messaging, `2010-04-01` | Supported | None |
| [Telnyx](/providers/telnyx) | Messaging API v2 | Supported | None |
| [Plivo](/providers/plivo) | Message API v1 | Partial | Plivo does not document its error body, so 4xx responses other than 401 and 429 are `request` and never fall back. |
| [Vonage](/providers/vonage) | Messages API v1, channel `sms` | Partial | Error classification is inferred. No short codes, no MMS. Basic auth gets no webhooks. |
| [Bandwidth](/providers/bandwidth) | Messaging API v2 | Partial | SMS only. Callbacks are unsigned and checked with Basic credentials. Errors classified by HTTP status; a 429 counts as a rate limit only with a Bandwidth error body. |
| [Sinch](/providers/sinch) | SMS API (`/xms/v1`) | Partial | No MMS. HMAC callback format is unpublished; Basic is the documented option. Few error codes classified. |

Supported adapters build requests, responses, error mapping, and webhooks from official documentation and pass the adapter contract tests. Partial adapters pass the same tests, but some provider behavior could not be confirmed from official documentation. Each provider page lists the gaps. Read the status at runtime from `adapter.support` or `sms.capabilities()`.

None of the providers documents send idempotency for SMS, so no adapter has native idempotency. See [Prevent duplicate sends](/sending/idempotency).

## Capabilities

| | Twilio | Telnyx | Plivo | Vonage (JWT) | Vonage (Basic) | Bandwidth | Sinch |
| --- | --- | --- | --- | --- | --- | --- | --- |
| MMS (`mediaUrls`) | ✅ max 10 | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Scheduling (`sendAt`) | ✅ Messaging Service only | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ |
| Validity period (`validityPeriodSec`) | 1 to 36,000 s | ❌ | 5 to 10,799 s | 20 to 604,800 s | 20 to 604,800 s | ❌ | 1 to 2,592,000 s |
| Per-message `webhookUrl` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
| Delivery status webhooks | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| Inbound webhooks | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| STOP/HELP detection | ✅ provider `OptOutType` | Keyword | Keyword | Keyword | ❌ | Keyword | Keyword |
| Webhook replay window | None | 300 s | None | 300 s | n/a | None | 300 s with HMAC, none with Basic |

Every adapter sends text. An unsupported field throws `UnsupportedFieldError` before any request, so nothing is sent. "Keyword" means SMS SDK detects STOP and HELP in the message text; Twilio also reports its own opt-out signal. Without a replay window, store each event's `dedupeKey` and skip repeats, as covered in [Webhook security](/receiving/webhook-security).

## Sender types

| Sender | Twilio | Telnyx | Plivo | Vonage | Bandwidth | Sinch |
| --- | --- | --- | --- | --- | --- | --- |
| Long code | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Toll-free | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Short code | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| Alphanumeric sender ID | ✅ | ✅ needs `messagingProfileId` | ✅ | ✅ | ❌ | ✅ |
| `{ messagingService }` | Messaging Service SID | Messaging profile ID | Powerpack UUID | ❌ | ❌ | ❌ |

This table says what the adapter can send from. The provider and the carriers decide whether your account may use that sender in a given country. Each provider page lists its rules under Senders, and [Registration and consent](/providers/registration-and-consent) covers 10DLC, toll-free verification, short codes, and sender IDs.

## Switching providers

Changing the adapter is one line of code. The account work takes longer: senders and their registrations belong to one provider account, and you need new webhook URLs and credentials. See [Switch providers](/migration/switch-providers) for the checklist.

For a provider that is not listed, see [Build your own adapter](/advanced/writing-an-adapter).
