SMS Quick Start

Last updated: 2024-02-28Contributors
Edit this page

Calling the RingCentral API for the first time? We recommend you try out getting started experience.

Enabling the phone numbers in your account for SMS

As a participating TCR CSP, RingCentral is dedicated to providing the highest quality of service, while working to eliminate spam, phishing, and fraudulent messages. To help ensure these goals are met, RingCentral requires customers to follow the TCR process to enable their account to send SMS. To learn more, read our TCR FAQ.

In addition, reading our SMS content and messaging policies may also help you in staying compliant.

In this Quick Start, we are going to help you send your first SMS on the platform in just a few minutes. Let's get started.

Create app and obtain credentials

The first thing we need to do is create an app in the RingCentral Developer Console. This can be done quickly by clicking the "Create SMS App" button below. Just click the button, enter a name and description if you choose, and click the "Create" button. If you do not yet have a RingCentral account, you will be prompted to create one.

Create SMS App

  1. Login or create an account if you have not done so already.
  2. Go to Console/Apps and click 'Create App' button.
  3. Select "REST API App" under "What type of app are you creating?" Click "Next."
  4. Under "Auth" select "JWT auth flow"
  5. Under "Security" add the following permissions:
    • SMS
    • ReadAccounts
  6. Under "Security" select "This app is private and will only be callable using credentials from the same RingCentral account."

When you are done, you will be taken to the app's dashboard. Make note of the Client ID and Client Secret. We will be using those momentarily.

Download and edit a .env file

Follow the instructions found in our guide to running Developer Guide code samples. Or:

  1. Download our env-template and save it as a file named .env.
  2. Edit your newly downloaded .env file, setting its variables with the proper values for the app you created above.
    • RC_CLIENT_ID - set to the Client ID of the app you created above
    • RC_CLIENT_SECRET - set to the Client Secret of the app you created above
    • RC_JWT - set to the JWT credential you created for yourself
    • SMS_RECIPIENT - for code testing purpose, we set the recipient's phone number to this environment variable. You can set the phone number via this variable, or you can set it directly on your code.

Send an SMS

Select your preferred language below.

Install RingCentral JavaScript SDK

$ npm install @ringcentral/sdk dotenv --save

Create and edit sms.js

Create a file called sms.js.

const RC = require('@ringcentral/sdk').SDK
const path = require('path')
// Remember to modify the path to where you saved your .env file!
require('dotenv').config({ path: path.resolve(__dirname, '../.env') })

// For the purpose of testing the code, we put the SMS recipient number in the environment variable.
// Feel free to set the SMS recipient directly.
const RECIPIENT    = process.env.SMS_RECIPIENT

// Instantiate the SDK and get the platform instance
var rcsdk = new RC({
    'server':       process.env.RC_SERVER_URL,
    'clientId':     process.env.RC_CLIENT_ID,
    'clientSecret': process.env.RC_CLIENT_SECRET
});
var platform = rcsdk.platform();

/* Authenticate a user using a personal JWT token */
platform.login({ 'jwt':  process.env.RC_JWT })

platform.on(platform.events.loginSuccess, function(e){
    read_extension_phone_number_detect_sms_feature()
});

platform.on(platform.events.loginError, function(e){
    console.log("Unable to authenticate to platform. Check credentials.", e.message)
    process.exit(1)
});

/*
  Read phone number(s) that belongs to the authenticated user and detect if a phone number
  has the SMS capability
*/
async function read_extension_phone_number_detect_sms_feature(){
    try {
        let endpoint = "/restapi/v1.0/account/~/extension/~/phone-number"
        var resp = await platform.get(endpoint)
        var jsonObj = await resp.json()
        for (var record of jsonObj.records){
            for (var feature of record.features){
                if (feature == "SmsSender"){
                    // If a user has multiple phone numbers, check and
            // decide which number to be used for sending
            // the SMS message. For simplicity, we pick the
            // first one we find. 
                    return send_sms(record.phoneNumber)
                }
            }
        }
        if (jsonObj.records.length == 0)
          console.log("This user does not own a phone number!")
        else
          console.log("None of this user's phone number(s) has the SMS capability!")
    } catch(e) {
        console.log(e.message)
        process.exit(1)
    }
}

/*
 Send a text message from a user own phone number to a recipient number
*/
async function send_sms(fromNumber){
    try {
        let bodyParams = {
            from: { phoneNumber: fromNumber },
            to: [ { phoneNumber: RECIPIENT} ],
            // To send group messaging, add more (max 10 recipients) 'phoneNumber' object. E.g.
            /*
            to: [
               { phoneNumber: RECIPIENT },
               { phoneNumber: 'Recipient-Phone-Number' }
             ],
            */
            text: 'Hello World!'
        }
        let endpoint = "/restapi/v1.0/account/~/extension/~/sms"
        var resp = await platform.post(endpoint, bodyParams)
        var jsonObj = await resp.json()
        console.log("SMS sent. Message id: " + jsonObj.id)
        check_message_status(jsonObj.id);
    } catch(e) {
        console.log(e.message)
        process.exit(1)
    }
}

/*
 Check the sending message status until it's out of the queued status
*/
async function check_message_status(messageId){
    try {
        let endpoint = `/restapi/v1.0/account/~/extension/~/message-store/${messageId}`
        let resp = await platform.get(endpoint);
        let jsonObj = await resp.json()
        console.log("Message status: ", jsonObj.messageStatus)
        if (jsonObj.messageStatus == "Queued"){
          await sleep (2000);
          check_message_status(jsonObj.id);
        }
    } catch (e) {
      console.log(e.message)
      process.exit(1)
    }
}

const sleep = async (ms) => {

Run your code

You are almost done. Now run your script.

$ node sms.js

Install RingCentral Python SDK

$ pip install ringcentral python-dotenv

Create and edit sms.py

Create a file called sms.py.

import os, sys, time
from dotenv import load_dotenv
from ringcentral import SDK

load_dotenv()

# Read phone number(s) that belongs to the authenticated user and detect if a phone number
# has the SMS capability
def read_extension_phone_number_detect_sms_feature():
  try:
    resp = platform.get("/restapi/v1.0/account/~/extension/~/phone-number")
    jsonObj = resp.json()
    for record in jsonObj.records:
      for feature in record.features:
        if feature == "SmsSender":
          # If user has multiple phone numbers, check and decide which number
          # to be used for sending SMS message.
          return send_sms(record.phoneNumber)
    if count(jsonObj.records) == 0:
      print("This user does not own a phone number!");
    else:
      print("None of this user's phone number(s) has the SMS capability!");
  except Exception as e:
    print (e.message)

# Send a text message from a user own phone number to a recipient number
def send_sms(fromNumber):
  try:
    bodyParams = {
         'from' : { 'phoneNumber': fromNumber },
         'to'   : [ {'phoneNumber': RECIPIENT} ],
         # To send group messaging, add more (max 10 recipients) 'phoneNumber' object. E.g.
         #
         #'to': [
         #       { 'phoneNumber': "Recipient1-Phone-Number" },
         #       { 'phoneNumber': "Recipient2-Phone-Number" }
         #     ],
         'text' : "Hello World!"
    }
    endpoint = "/restapi/v1.0/account/~/extension/~/sms"
    resp = platform.post(endpoint, bodyParams)
    jsonObj = resp.json()
    print ("SMS sent. Message id: " + str(jsonObj.id))
    check_message_status(jsonObj.id)
  except Exception as e:
    print (e)

# Check the sending message status until it's out of the queued status
def check_message_status(messageId):
  try:
    endpoint = "/restapi/v1.0/account/~/extension/~/message-store/" + str(messageId)
    resp = platform.get(endpoint)
    jsonObj = resp.json()
    print ("Message status: " + jsonObj.messageStatus)
    if (jsonObj.messageStatus == "Queued"):
      time.sleep(2)
      check_message_status(jsonObj.id)
  except Exception as e:
    print (e)

# Instantiate the SDK and get the platform instance
rcsdk = SDK( os.environ.get('RC_CLIENT_ID'),
             os.environ.get('RC_CLIENT_SECRET'),
             os.environ.get('RC_SERVER_URL') )
platform = rcsdk.platform()

# For the purpose of testing the code, we put the SMS recipient number in the environment variable.
# Feel free to set the SMS recipient directly.
RECIPIENT    = os.environ.get('SMS_RECIPIENT')

# Authenticate a user using a personal JWT token
def login():
    try:
      platform.login( jwt=os.environ.get('RC_JWT') )
      read_extension_phone_number_detect_sms_feature()
    except Exception as e:
      sys.exit("Unable to authenticate to platform. Check credentials." + str(e))

login()

Run your code

You are almost done. Now run your script.

$ python sms.py

Install RingCentral PHP SDK

$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar require ringcentral/ringcentral-php vlucas/phpdotenv

Create and edit sms.php

Create a file called sms.php.

<?php
// Remember to modify the path ./../ pointing to the location where the RingCentral SDK was installed and the .env file was saved!
require('./../vendor/autoload.php');
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->load();

// For the purpose of testing the code, we put the SMS recipient number in the environment variable.
// Feel free to set the SMS recipient directly.
$RECIPIENT    = $_ENV['SMS_RECIPIENT'];

# Instantiate the SDK and get the platform instance
$rcsdk = new RingCentral\SDK\SDK( $_ENV['RC_CLIENT_ID'],
                                  $_ENV['RC_CLIENT_SECRET'],
                                  $_ENV['RC_SERVER_URL'] );
$platform = $rcsdk->platform();

// Authenticate a user using a personal JWT token
try {
  $platform->login( [ "jwt" => $_ENV['RC_JWT'] ] );
  read_extension_phone_number_detect_sms_feature();
} catch (\RingCentral\SDK\Http\ApiException $e) {
  exit("Unable to authenticate to platform. Check credentials. " . $e->message . PHP_EOL);
}

/*
  Read phone number(s) that belongs to the authenticated user and detect if a phone number
  has the SMS capability
*/
function read_extension_phone_number_detect_sms_feature(){
  global $platform;
  $endpoint = "/restapi/v1.0/account/~/extension/~/phone-number";
  $resp = $platform->get($endpoint);
  $jsonObj = $resp->json();
  foreach ($resp->json()->records as $record){
    foreach ($record->features as $feature){
      if ($feature == "SmsSender"){
        // If a user has multiple phone numbers, check and decide which number
        // to be used for sending SMS message.
        return send_sms($record->phoneNumber);
      }
    }
  }
  if (count($jsonObj->records) == 0){
    exit("This user does not own a phone number!");
  }else{
    exit("None of this user's phone number(s) has the SMS capability!");
  }
}

/*
 Send a text message from a user own phone number to a recipient number
*/
function send_sms($fromNumber){
  global $platform, $RECIPIENT;
  try {
    $requestBody = array(
       'from' => array ('phoneNumber' => $fromNumber),
       'to' => array( array('phoneNumber' => $RECIPIENT) ),
       // To send group messaging, add more (max 10 recipients) 'phoneNumber' object. E.g.
       /*
       'to' => array(
          array('phoneNumber' => $RECIPIENT),
          array('phoneNumber' => 'Recipient-Phone-Number')
        ),
       */
       'text' => 'Hello World!'
    );
    $endpoint = "/account/~/extension/~/sms";
    $resp = $platform->post($endpoint, $requestBody);
    $jsonObj = $resp->json();
    print("SMS sent. Message id: " . $jsonObj->id . PHP_EOL);
    check_message_status($jsonObj->id);
  } catch (\RingCentral\SDK\Http\ApiException $e) {
    exit("Error message: " . $e->message . PHP_EOL);
  }
}

/*
 Check the sending message status until it's out of the queued status
*/
function check_message_status($messageId){
    global $platform;
    try {
        $endpoint = "/restapi/v1.0/account/~/extension/~/message-store/".$messageId;
        $resp = $platform->get($endpoint);
        $jsonObj = $resp->json();
        print("Message status: " . $jsonObj->messageStatus . PHP_EOL);
        if ($jsonObj->messageStatus == "Queued"){
          sleep(2);
          check_message_status($jsonObj->id);
        }
    } catch (\RingCentral\SDK\Http\ApiException $e) {
      exit("Error message: " . $e->message . PHP_EOL);
    }
}
?>

Run your code

You are almost done. Now run your script.

$ php sms.php

Install RingCentral Ruby SDK

$ gem install ringcentral-sdk dotenv

Create and edit sms.rb

Create a file called sms.rb.

require 'ringcentral'
require 'dotenv'
# Remember to modify the path to where you saved your .env file!
Dotenv.load("./../.env")

# For the purpose of testing the code, we put the SMS recipient number in the environment variable.
# Feel free to set the SMS recipient directly.
RECIPIENT    = ENV['SMS_RECIPIENT']

# Read phone number(s) that belongs to the authenticated user and detect if a phone number
# has the SMS capability
def read_extension_phone_number_detect_sms_feature()
  begin
    endpoint = "/restapi/v1.0/account/~/extension/~/phone-number"
    resp = $platform.get(endpoint)
    for record in resp.body['records'] do
      for feature in record['features'] do
        if feature == "SmsSender"
          # If user has multiple phone numbers, check and decide which number
          # to be used for sending SMS message.
          return send_sms(record['phoneNumber'])
        end
      end
    end
    if resp.body['records'].length == 0
      puts ("This user does not own a phone number!")
    else
      puts("None of this user's phone number(s) has the SMS capability!")
    end
  rescue StandardError => e
    puts (e)
  end
end

# Send a text message from a user own phone number to a recipient number
def send_sms(fromNumber)
  begin
    bodyParams = {
          from: { phoneNumber: fromNumber },
          to: [{ phoneNumber: RECIPIENT }],
          # To send group messaging, add more (max 10 recipients) 'phoneNumber' object. E.g.
          #
          #to: [
          #       { phoneNumber: RECIPIENT },
          #       { phoneNumber: 'Recipient-Phone-Number' }
          #     ],
          text: 'Hello World!'
      }
    endpoint =  "/restapi/v1.0/account/~/extension/~/sms"
    resp = $platform.post(endpoint, payload: bodyParams)
    puts ("SMS sent. Message id: " + resp.body['id'].to_s)
    check_message_status(resp.body['id'])
  rescue StandardError => e
    puts (e)
  end
end

# Check the sending message status until it's out of the queued status
def check_message_status(messageId)
  begin
    endpoint = "/restapi/v1.0/account/~/extension/~/message-store/" + messageId.to_s
    resp = $platform.get(endpoint)
    puts ("Message status: " + resp.body['messageStatus'])
    if (resp.body['messageStatus'] == "Queued")
      sleep(2)
      check_message_status(resp.body['id'])
    end
  rescue StandardError => e
    puts (e)
  end
end

# Instantiate the SDK and get the platform instance
$platform = RingCentral.new( ENV['RC_CLIENT_ID'], ENV['RC_CLIENT_SECRET'], ENV['RC_SERVER_URL'] )

# Authenticate a user using a personal JWT token
def login()
  begin
    $platform.authorize(jwt: ENV['RC_JWT'])
    read_extension_phone_number_detect_sms_feature()
  rescue StandardError => e
    puts ("Unable to authenticate to platform. Check credentials." + e.to_s)
  end
end

login()
##############################

Run your code

You are almost done. Now run your script.

$ ruby sms.rb

Create a Visual Studio project

  • Choose Console Application .Net Core -> App
  • Select Target Framework .NET Core 2.1 or higher version
  • Enter project name "Send_SMS"
  • Add NuGet package RingCentral.Net (6.0.0) SDK
  • Save the .env file under your project folder. E.g. /Send_SMS/bin/Debug/netcoreapp2.2/.env

Edit the file Program.cs

using System;
using System.Threading.Tasks;
using RingCentral;
using dotenv.net;

namespace Send_SMS
{
    class Program
    {
        static string RECIPIENT;
        static RestClient restClient;
        static async Task Main(string[] args)
        {
          try
          {
            DotEnv.Load();
            // Instantiate the SDK
            restClient = new RestClient(
                Environment.GetEnvironmentVariable("RC_CLIENT_ID"),
                Environment.GetEnvironmentVariable("RC_CLIENT_SECRET"),
                Environment.GetEnvironmentVariable("RC_SERVER_URL"));
            // Authenticate a user using a personal JWT token
            await restClient.Authorize( Environment.GetEnvironmentVariable("RC_JWT") );

            // For the purpose of testing the code, we put the SMS recipient number in the environment variable.
            // Feel free to set the SMS recipient directly.
            RECIPIENT = Environment.GetEnvironmentVariable("SMS_RECIPIENT");

            await read_extension_phone_number_detect_sms_feature();
          }
          catch (Exception ex)
          {
            Console.WriteLine(ex.Message);
          }
        }

        /*
          Read phone number(s) that belongs to the authenticated user and detect if a phone number
          has the SMS capability
        */
        static private async Task read_extension_phone_number_detect_sms_feature()
        {
            try
            {
                var resp = await restClient.Restapi().Account().Extension().PhoneNumber().Get();
                foreach (var record in resp.records)
                {
                    foreach (var feature in record.features)
                    {
                        if (feature == "SmsSender")
                        {
                            // If a user has multiple phone numbers, check and decide which number
                            // to be used for sending SMS message.
                            await send_sms(record.phoneNumber);
                            return;
                        }
                    }
                }
                if (resp.records.Length == 0)
                {
                    Console.WriteLine("This user does not own a phone number!");
                }
                else
                {
                    Console.WriteLine("None of this user's phone number(s) has the SMS capability!");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        /*
         Send a text message from a user own phone number to a recipient number
        */
        static private async Task send_sms(string fromNumber)
        {
            try
            {
                var requestBody = new CreateSMSMessage();
                requestBody.from = new MessageStoreCallerInfoRequest
                {
                    phoneNumber = fromNumber
                };
                requestBody.to = new MessageStoreCallerInfoRequest[] {
                    new MessageStoreCallerInfoRequest { phoneNumber = RECIPIENT }
                };
                // To send group messaging, add more (max 10 recipients) 'phoneNumber' object. E.g.
                /*
                requestBody.to = new MessageStoreCallerInfoRequest[] {
                  new MessageStoreCallerInfoRequest { phoneNumber = "Recipient_1_Number" },
                  new MessageStoreCallerInfoRequest { phoneNumber = "Recipient_2_Number" }
                };
                */
                requestBody.text = "Hello World!";

                var resp = await restClient.Restapi().Account().Extension().Sms().Post(requestBody);
                Console.WriteLine("SMS sent. Message id: " + resp.id.ToString());
                await check_message_status(resp.id.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        /*
         Check the sending message status until it's no longer in the queued status
        */
        static private async Task check_message_status(string messageId)
        {
            try
            {
                var resp = await restClient.Restapi().Account().Extension().MessageStore(messageId).Get();
                Console.WriteLine("SMS message status: " + resp.messageStatus);
                if (resp.messageStatus == "Queued")
                {
                    Thread.Sleep(2000);
                    await check_message_status(resp.id.ToString());
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

Run Your App

You are almost done. Now run your app from Visual Studio.

Create a Java project (using Eclipse IDE)

  • Create a new Java project
  • Select the Gradle Project wizard
  • Enter project name "SendSMS"
  • Open the build.gradle file and add the RingCentral Java SDK to the project as shown below:

    dependencies {
        // ...
        compile 'com.ringcentral:ringcentral:3.0.0'
    }
    
  • On Eclipse menu, select "Run" and choose the "Run Configurations" and in the dialog, select your project and select the "Environments" tab then enter the following variables:

    • RC_CLIENT_ID
    • RC_CLIENT_SECRET
    • RC_SERVER_URL
    • RC_JWT
    • SMS-RECIPIENT
  • Right-click the project in the Package Explorer and choose "Refresh Gradle Project" under the "Gradle" sub-menu

Create a new Java Class

Select "File -> New -> Class" to create a new Java class named "SendSMS"

package SendSMS;

public class SendSMS {

  public static void main(String[] args) {
    // TODO Auto-generated method stub

  }
}

Edit the file "SendSMS.java".

package SendSMS;

import java.io.IOException;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;

import com.ringcentral.*;
import com.ringcentral.definitions.*;

public class SendSMS {
    static RestClient restClient;
    static String RECIPIENT = "";
    public static void main(String[] args) {
      var obj = new SendSMS();
      try {
        // Instantiate the SDK
        restClient = new RestClient(System.getenv("RC_CLIENT_ID"), System.getenv("RC_CLIENT_SECRET"), System.getenv("RC_SERVER_URL"));

        // Authenticate a user using a personal JWT token
        restClient.authorize(System.getenv("RC_JWT"));

        // For the purpose of testing the code, we put the SMS recipient number in the environment variable.
        // Feel free to set the SMS recipient directly.
        RECIPIENT = System.getenv("SMS_RECIPIENT");

        obj.read_extension_phone_number_detect_sms_feature();
      } catch (RestException e) {
        System.out.println(e.getMessage());
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    /*
     Read phone number(s) that belongs to the authenticated user and detect if a phone number
     has the SMS capability
    */
    public void read_extension_phone_number_detect_sms_feature() throws IOException {
      try {
        var resp =  restClient.restapi().account().extension().phoneNumber().get();
        for (var record : resp.records) {
          if (record.usageType.equalsIgnoreCase("DirectNumber")) {
            for(var feature : record.features) {
              if (feature.equalsIgnoreCase("SmsSender")) {
                // If a user has multiple phone numbers, check and decide which number
                // to be used for sending SMS message.
                send_sms(record.phoneNumber);
                return;
              }
            }
          }
        }
        if (resp.records.length == 0) {
          System.out.println("This user does not own a phone number!");
        } else {
          System.out.println("None of this user's phone number(s) has the SMS capability!");
        }
      }catch(RestException e) {
        System.out.println(e.getMessage());
      }
    }
    /*
     Send a text message from a user own phone number to a recipient number
    */
    public void send_sms(String fromNumber) throws IOException {
      try {
        CreateSMSMessage requestBody = new CreateSMSMessage();
        requestBody.from = new MessageStoreCallerInfoRequest().phoneNumber(fromNumber);

        requestBody.to = new MessageStoreCallerInfoRequest[] {
          new MessageStoreCallerInfoRequest().phoneNumber(RECIPIENT)
        };

        // To send group messaging, add more (max 10 recipients) 'phoneNumber' object. E.g.
        /*
        requestBody.to = new MessageStoreCallerInfoRequest[] {
          new MessageStoreCallerInfoRequest().phoneNumber("Recipient_1_Number"),
          new MessageStoreCallerInfoRequest().phoneNumber("Recipient_2_Number")
        };
        */
        requestBody.text = "Hello World";

        var resp = restClient.restapi().account().extension().sms().post(requestBody);
        System.out.println("SMS sent. Message id: " + resp.id.toString());
        check_sms_message_status(resp.id.toString());
      } catch(RestException e) {
        System.out.println(e.getMessage());
      }
  }
  /*
    Check the sending message status until it's no longer in the queued status
  */
  private void check_sms_message_status(String messageId) throws IOException {
    try {
      var resp = restClient.restapi().account().extension().messageStore(messageId).get();
      System.out.println("SMS message status: " + resp.messageStatus);
      if (resp.messageStatus.equals("Queued")) {
        try {
          Thread.sleep(2000);
          check_sms_message_status(resp.id.toString());
        } catch (InterruptedException e) {
          e.printStackTrace();
          System.out.println(e);
        }
      }
    } catch (RestException e) {
      System.out.println(e.getMessage());
    }
  }
}

Run Your App

You are almost done. Now run your app from Eclipse.

Need Help?

Having difficulty? Feeling frustrated? Receiving an error you don't understand? Our community is here to help and may already have found an answer. Search our community forums, and if you don't find an answer please ask!

Search the forums »

What's Next?

When you have successfully made your first API call, it is time to take your next step towards building a more robust RingCentral application.

Take your next step »