Remote Site Settings:

Sample Code:
Without Media URL:
/**
* Handles outbound SMS messaging via the Twilio REST API.
* Sends a text message from a configured Twilio number to the specified recipient.
*/
public class TwilioSMSHandler {
/**
* Sends an SMS message to the given phone number using Twilio.
*
* @param strPhone Recipient phone number in E.164 format (e.g. +1XXXXXXXXXX)
* @param smsBody Text content of the SMS message
*/
public static void send(String strPhone, String smsBody) {
// Best Practice: Move credentials to Named Credentials or Custom Metadata Types.
// Hardcoded values are a security risk and make rotation difficult.
final String fromNumber = 'FROM_NUMBER';
String strAccount = 'ACCOUNT_SID';
String token = 'ACCESS_TOKEN';
// Build the HTTP POST request targeting the Twilio Messages endpoint
HttpRequest req = new HttpRequest();
req.setEndpoint('https://api.twilio.com/2010-04-01/Accounts/' + strAccount + '/Messages');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
// Encode credentials as Base64 for HTTP Basic authentication
Blob headerValue = Blob.valueOf(strAccount + ':' + token);
String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
req.setHeader('Authorization', authorizationHeader);
if (strPhone != null) {
// URL-encode all values to safely handle special characters
req.setBody(
'To=' + EncodingUtil.urlEncode(strPhone, 'UTF-8') +
'&From=' + EncodingUtil.urlEncode(fromNumber, 'UTF-8') +
'&Body=' + EncodingUtil.urlEncode(smsBody, 'UTF-8')
);
try {
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug('Response Body is ' + res.getBody());
// Twilio returns HTTP 201 Created on success
if (res.getStatusCode() == 201) {
System.debug('Twilio Success ' + strPhone);
} else {
System.debug('Twilio failed ' + strPhone);
ErrorResponseWrapper erw = (ErrorResponseWrapper) JSON.deserialize(res.getBody(), ErrorResponseWrapper.class);
System.debug('Twilio error ' + erw.message);
}
} catch (Exception e) {
System.debug('Exception is ' + e);
}
}
}
/**
* Maps the Twilio API error response body for failed requests.
*/
public class ErrorResponseWrapper {
public String code;
public String message;
public String moreInfo;
public String status;
}
}
With Media URL:
public class TwilioSMSHandler {
public static void send( String strPhone ) {
ErrorResponseWrapper erw;
String smsBody = 'Test Message';
String strMediaURL = 'IMAGE_URL_WITH_EXTENSION';
final String fromNumber = 'FROM_NUMBER';
String account = 'ACCOUNT_SID';
String token = 'ACCESS_TOKEN';
HttpRequest req = new HttpRequest();
req.setEndpoint( 'https://api.twilio.com/2010-04-01/Accounts/' + account + '/Messages' );
req.setMethod( 'POST' );
req.setHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
Blob headerValue = Blob.valueOf( account + ':' + token );
String authorizationHeader = 'BASIC ' +
EncodingUtil.base64Encode( headerValue );
req.setHeader( 'Authorization', authorizationHeader );
if ( strPhone != null ) {
req.setBody( 'To=' + EncodingUtil.urlEncode( strPhone, 'UTF-8' ) + '&From=' + fromNumber + '&Body=' + smsBody + '&MediaUrl=' + strMediaURL );
try {
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug( 'Response Body is ' + res.getBody() );
if ( res.getStatusCode() == 201 )
system.debug( 'Twilio Success ' + strPhone );
else {
system.debug( 'Twilio failed ' + strPhone );
erw = ( ErrorResponseWrapper )json.deserialize( res.getBody(), ErrorResponseWrapper.class );
system.debug( 'Twilio error ' + erw.message );
}
} catch( Exception e ) {
system.debug( 'Exception is ' + e );
}
}
}
public class ErrorResponseWrapper {
String code;
String message;
String moreInfo;
String status;
}
}