How to send SMS text messages with PHP
- Prerequisites
- How to send text messages with PHP (using the MailerSend SMS API)
- How to check the status of your message
- How to use personalization in text messages
- How to send SMS in bulk
- SMS response codes and error messages
- Best practices for sending SMS with PHP
- MailerSend pricing
- Sending SMS with PHP is simple
Transactional SMS notifications are a great way for businesses to reach customers. It’s quick, it’s reliable, and in fact, SMS has a 98%+ open rate, much higher than that of email.
The good news is, you can use good old PHP combined with an advanced REST API and SMS gateway to effortlessly implement SMS sending.
In this tutorial, we’ll go through how to send SMS messages (with PHP code examples) and the best practices for sending transactional SMS.
Prerequisites
Combining MailerSend’s SMS API and the PHP SDK is a quick and easy way to start sending bulk SMS. But there are a few things you’ll need to have ready before you can start sending.
Account with an SMS provider: MailerSend’s Starter and Professional plans include SMS, which you can test for free with a trial phone number. Note: MailerSend’s SMS feature is currently available for the US and Canada.
Verified phone number: For testing, you can use your Trial number. To get started with your own number, you’ll need to purchase a number and verify it. To purchase a phone number:
Go to Plan and billing.
Select the Phone number add-on.
Choose a phone number and click Add to cart.
Complete the purchase and verify your phone number.
For more information, read How to purchase a phone number.
API token with SMS permissions: To create a new API key in MailerSend, go to Integrations > API tokens - Manage > Create new token.
PHP environment with API installed: PHP 7.4, PSR-7 and PSR-18 based HTTP adapter. To install the correct implementations for PSR-7 and PSR-18:
composer require php-http/guzzle7-adapter nyholm/psr7
And to install MailerSend:
composer require mailersend/mailersend
How to send text messages with PHP (using the MailerSend SMS API)
1. Create a PHP project named SendSms.php and configure your authentication credentials by adding your API key as an environment variable named MAILERSEND_API_KEY.
2. If you haven’t already, install the MailerSend PHP SDK:
composer require mailersend/mailersend
3. To start sending SMS, save the following code to your PHP file. Remember to load your API key with getenv().
<?php
require __DIR__ . "/../vendor/autoload.php";
use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\SmsParams;
$mailersend = new MailerSend([
"api_key" => getenv("MAILERSEND_API_KEY"),
]);
$smsParams = (new SmsParams())
->setFrom("+12065550101")
->setTo(["+12065550102", "+12065550103"])
->setText("This text message is a test.");
$sms = $mailersend->sms->send($smsParams);
Run the code and your SMS will be sent!
Request parameters
Required:
from: The number being used to send the message (your account phone number) in E164 format
to: The numbers(s) the message is being sent to in E164 format
text: The contents of the SMS message
Optional:
personalization: Personalization of the message through the use of {{var}} variables
Learn more about request parameters in our API docs.
How to check the status of your message
You can check the status of any text message you have sent via 2 methods: through the API or in the app.
To check the status via API, use the following code, replacing sms_message_id with the actual message ID:
<?php
require __DIR__ . '/../vendor/autoload.php';
use MailerSend\MailerSend;
$mailersend = new MailerSend([
'api_key' => getenv('MAILERSEND_API_KEY')
]);
$smsMessage = $mailersend->smsMessage->find('sms_message_id');
Your message will either be processed, queued, sent, delivered, or failed. The response will look something like this:
{
"data": {
"id": "01h909rj94ybjnvpke60w866n6",
"from": "+18332647501",
"to": [
"+16203221059"
],
"text": "This text message is a test.",
"paused": false,
"created_at": "2023-08-29T09:24:58.000000Z",
"sms": [
{
"id": "01h909rjj42mjxcpkxv6asq1jn",
"from": "+18332647501",
"to": "+16203221059",
"text": "This text message is a test.",
"compiled_text": "This text message is a test.",
"status": "sent",
"segment_count": 1,
"error_type": null,
"error_description": null,
"created_at": "2023-08-29T09:24:59.000000Z"
}
],
"sms_activity": [
{
"from": "+18332647501",
"to": "+16203221059",
"created_at": "2023-08-29T09:24:59.000000Z",
"status": "processed",
"sms_message_id": "01h909rj94ybjnvpke60w866n6"
},
{
"from": "+18332647501",
"to": "+16203221059",
"created_at": "2023-08-29T09:24:59.000000Z",
"status": "queued",
"sms_message_id": "01h909rj94ybjnvpke60w866n6"
},
{
"from": "+18332647501",
"to": "+16203221059",
"created_at": "2023-08-29T09:24:59.000000Z",
"status": "sent",
"sms_message_id": "01h909rj94ybjnvpke60w866n6"
}
]
}
}To check the status in the MailerSend app, simply navigate to SMS and Activity.
Tracking delivery with webhooks
You can optimize SMS delivery tracking with webhooks to listen for sent, delivered and failed events, allowing you to send a callback with a payload about the text message that was sent. This provides the most recent information and data on message activity without requiring constant API polling.
When a webhook is fired for a particular event, you can trigger a workflow (for example, if an SMS fails, use a fallback mechanism such as sending the message through an alternative channel) or set up real-time notifications to monitor for potential issues.
The available webhook events in MailerSend are sms.sent, sms.delivered and sms.failed.
How to use personalization in text messages
You can add variables to your text messages using the personalization parameter. Personalization variables can be added to the text fields using {{ var }} syntax. Here is the sample code to send an SMS with a personalization variable.
<?php
require __DIR__ . "/../vendor/autoload.php";
use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\SmsParams;
$mailersend = new MailerSend([
"api_key" => getenv("MAILERSEND_API_KEY"),
]);
$smsParams = (new SmsParams())
->setFrom("+12065550101")
->setTo(["+12065550102"])
->setText("Text {{ var }}")
->setPersonalization([
new SmsPersonalization("+12065550102", [
"var" => "variable",
"number" => 123,
"object" => [
"key" => "object-value",
],
"objectCollection" => [
[
"name" => "John",
],
[
"name" => "Patrick",
],
],
]),
]);
$sms = $mailersend->sms->send($smsParams);
For the personalization of each text message, add the “personalization” object with each phone number and data objects as key: value pairs.
"personalization": [
{
"phone_number": "+19191234567",
"data": {
"name": "Dummy"
}
}
]
How to send SMS in bulk
You can send the same SMS content to multiple recipients (up to 50) by simply adding their numbers as an array. But if you want to send personalized messages to multiple recipients in a single request, you can do so by looping through recipients.
The example below creates a recipient list with personalization data, loops through each one and builds a text message, and then sends each SMS individually.
<?php
require __DIR__ . '/../vendor/autoload.php';
use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\SmsParams;
$mailersend = new MailerSend([
'api_key' => getenv('MAILERSEND_API_KEY')
]);
$recipients = [
[
'phone' => '+12065550102',
'name' => 'Alice'
],
[
'phone' => '+12065550103',
'name' => 'Bob'
]
];
foreach ($recipients as $recipient) {
$text = "Hi {$recipient['name']}, your order has shipped!";
$smsParams = (new SmsParams())
->setFrom('+1234567890')
->setTo([$recipient['phone']])
->setText($text);
$mailersend->sms->send($smsParams);
}
On the Activity page, we can see that each message was delivered personalized with the recipient’s name.
SMS response codes and error messages
When you send a request to send an SMS, MailerSend will check that your text message is valid. Your SMS will then either be queued or sent, and if found to be invalid, you’ll receive an error response.
Sending queued response (202 accepted)
If there are no errors, you’ll receive the following HTTP response:
Response Code: 202 Accepted
Response Headers:
Content-Type: text/plain; charset=utf-8
X-SMS-Message-Id: 5e42957d51f1d94a1070a733
Response Body: [EMPTY]If your from phone number cannot be validated, you’ll receive the following validation error message:
Response Code: 422 Unprocessable Entity
Response Headers:
Content-Type: application/json
{
"message": "The given data was invalid.",
"errors": {
"from": [
"The from field contains an invalid number."
]
}
}Other MailerSend SMS delivery codes:
Code | Description | ||
4301: malformed-invalid-encoding | The message contains unsupported characters. MailerSend cannot re-encode the message. | ||
4302: malformed-invalid-from-number | The From number is not routable to a carrier or is invalid. | ||
4303: malformed-invalid-to-number | The To number is not routable to a carrier or is invalid. | ||
4403: rejected-forbidden-from-number | Messaging from the number is forbidden, most commonly because the number does not belong to MailerSend or the account. | ||
4404: rejected-forbidden-to-number | Messaging to the number is forbidden. This could be because the number is not active, not enabled for messaging, or is an invalid number. | ||
4412: media-content-invalid | The media content type is not supported. | ||
4420: rejected-carrier-does-not-exist | The upstream carrier associated with the message does not exist in the MailerSend configuration. | ||
4470: rejected-spam-detected | This message has been filtered and blocked by MailerSend as spam. |
Check out the complete list of SMS delivery codes and API response codes.
Best practices for sending SMS with PHP
1. Use a valid sender number
To ensure that your text messages are sent without errors and to provide the best possible experience for recipients, make sure you send your messages from a valid phone number. The number has to be a trial number or an active number on your account.
2. Use the E164 format
When entering phone numbers for senders and recipients, you must stick to the E164 format. This includes a maximum of 15 digits, and numbers start with a plus sign (+) followed by the country code (e.g., 1 for the U.S.) and the mobile number.
You can use Google’s libphonenumber library to validate and format phone numbers.
composer require giggsey/libphonenumber-for-php
Here’s an example script that checks the number and outputs it in E164 format:
<?php
require __DIR__ . "/../vendor/autoload.php";
use libphonenumber\PhoneNumberUtil;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\NumberParseException;
$phoneUtil = PhoneNumberUtil::getInstance();
// Change this number to test different inputs
$input = "+18974657286";
try {
$number = $phoneUtil->parse($input, null);
if ($phoneUtil->isValidNumber($number)) {
$e164 = $phoneUtil->format($number, PhoneNumberFormat::E164);
echo "Valid phone number\n";
echo "E.164 format: " . $e164 . "\n";
} else {
echo "Invalid phone number\n";
}
} catch (NumberParseException $e) {
echo "Invalid phone number: could not parse input\n";
}
3. Remember your character limits
If using GSM-7 encoding, you can include up to 160 characters per segment. If using UCS-2 encoding, for languages such as Arabic, Chinese, Korean, or Cyrillic alphabet languages, etc., there is a limit of up to 70 characters per segment. UCS-2 encoding is also used for sending emojis.
In MailerSend, there are no limits to the number of characters—or segments—you can send, however, you will be billed by segment.
4. Provide unsubscribe instructions
To be in accordance with MailerSend’s terms of use and the Cellular Telecommunications Industry Association’s (CTIA) guidelines, you must provide a way for recipients to opt out of receiving your text messages. To do this, you can use the STOP command, which allows recipients to reply to your text with “STOP”, “Stop” or “stop” to opt out.
Learn more about SMS compliance and head over to our guide on how to handle opt in and opt out for SMS.
MailerSend pricing
MailerSend’s flexible pricing makes it easy to get started with SMS and scale your sendings as necessary. Our Starter plan starts at just $28 a month for 50,000 emails and 100 SMS. After that, you’ll only pay for the additional SMS you send, at a rate of $1.40/100 SMS.
Learn more about SMS use cases:
Need more text messages? You can easily upgrade your plan to increase your SMS quota and get better pricing on additional SMS.
Check out our plans and pricing.
Sending SMS with PHP is simple
By using an advanced SMS API, ready-to-go PHP SDK, and the examples above, you can start sending personalized text messages directly to customers' phones in minutes. Just remember to follow technical best practices, obtain opt-in consent, and use a provider that follows CTIA guidelines.