How to Use bash or zsh to Send an SMS from a New Twilio Number

Let's level up our shell hacking skills by utilizing the Twilio API to send a text message directly in bash or zsh.  We'll walk through finding an available number, purchasing it, and sending SMSes all without leaving the comfort of the command line.

Let's get started!

Set Your Twilio Credentials in bash or zsh

Start by clicking over to the Twilio console.  Either log-in or sign up for a free account (be sure to verify your number), and look for the Account Summary as seen below:

Twilio Account Summary section of the console

You'll want to replace the 'account_sid' and 'auth_token' variables below with the 'ACCOUNT SID' and 'AUTH TOKEN' variables from the Twilio Console.  Click the eyeball icon to expose your auth token then copy/paste it into the shell.

account_sid="ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
auth_token="your_auth_token"

Find a Twilio number with cURL in bash and zsh

With our account SID and auth token configured, we can now query the Twilio REST API for programmable phone numbers. We need one to send an SMS from in our script.

available_number=`curl -X GET \
    "https://api.twilio.com/2010-04-01/Accounts/${account_sid}/AvailablePhoneNumbers/US/Local"  \
    -u "${account_sid}:${auth_token}" | \
    sed -n "/PhoneNumber/{s/.*<PhoneNumber>//;s/<\/PhoneNumber.*//;p;}"` \
    && echo $available_number 

Copying and pasting that command will set the variable available_number to the first available number Twilio returns.  

We're doing a few things in this line - let's unpack them here.

  1. available_number= in bash or zsh is the syntax for setting a local variable.  The backtick ( ` ) characters mean that what the ticks contain will be executed and set to available_number.
  2. curl -X GET "https://api.twilio.com/[omitted] -u "${account_sid}:${auth_token}" Uses the software package cURL and the HTTP verb GET to ask Twilio's available numbers endpoint for an available number.  '-u' signifies that we will be providing account credentials by HTTP Basic Auth. The ${variable_name} syntax inside of double quotes substitutes the variable names we set earlier into the command.
  3. "|" A pipe character in the shell means the results of the previous command are passed to the next.
  4. sed -n "/PhoneNumber/{s/.*<PhoneNumber>//;s/<\/PhoneNumber.*//;p;}" Uses the stream manipulating package sed to extract just the first occurrence of the <PhoneNumber> tags from Twilio's XML response
  5. && the double ampersands mean that the following command will be run immediately after the others finish
  6. echo $available_number is a sanity check that we received an output, printing the variable's contents in the shell.

(For advanced users: note that the 'US' after AvailablePhoneNumbers in the URI is the ISO Country Code.)

Note: If you're not in a trial account, you are about to spend money to buy a number.  Check out our pricing page for more details.

Purchase a Twilio Phone Number in bash or zsh

Now that we've found a Twilio phone number that's available for purchase, we need to put a ring on it. The following command will purchase the phone number we just found and add it to our account.

curl -X POST -F "PhoneNumber=${available_number}" \
    "https://api.twilio.com/2010-04-01/Accounts/${account_sid}/IncomingPhoneNumbers" \
    -u "${account_sid}:${auth_token}"

After executing the above, you'll be the happy owner of a new Twilio-provided phone number (if you aren't, the number may have just been purchased - you can re-run the 'available number' step and try again).  Note a few changes here when we use cURL with the IncomingNumber endpoint:

  • We're now using the HTTP method POST
  • We're POSTing the PhoneNumber parameter to the IncomingPhoneNumbers endpoint, and substituting the phone number we found in the last step

Assuming everything completed successfully and you now own the $available_number, we're almost ready for the big payoff.

Send an SMS with Twilio in bash or zsh

Change the your_number variable below to your verified Twilio number and execute the following:

your_number="+15555555555"
curl -X POST -F "Body=Hi there, your new phone number is working." \
    -F "From=${available_number}" -F "To={$your_number}" \
    "https://api.twilio.com/2010-04-01/Accounts/${account_sid}/Messages" \
    -u "${account_sid}:${auth_token}"

This command will send a POST request to the Messages resource with three required parameters: Body, From, and To. You can explore all of the variables for the Messages endpoint to see how you can send images, or set callback URLs to get updated on message delivery status.

If everything went well, you should now have a buzzing, beeping, or blinking phone. Try sending SMSes to other numbers, or even changing the body to add emojis.

With Twilio in Your Shell, The World is Your Oyster

Poking at the Twilio API without leaving the comfort of your favorite shell is a great way to explore the Twilio API and add communication to your command line scripts.  You can now search for numbers, purchase numbers, and send SMS messages using built-in *NIX tools and zsh or bash.

Further study: 

Paul Kamp
Kevin Whinnery
David Prothero

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd browsing the Twilio tag on Stack Overflow.