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

November 22, 2016
Written by
Paul Kamp
Reviewed by
Kat King
Tony Smith


Let’s level up our shell hacking skills by utilizing Twilio's Programmable Messaging 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 values of the account_sid and auth_token variables shown below with the ACCOUNT SID and AUTH TOKEN variables copied from the Twilio Console. Click the eyeball icon to expose your auth token then copy and paste it into the shell.


These values are not generated at the command line — we’ve just taken them from your Twilio account page in the Console and manually added them to variables that we’ll put to use in the next step.

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 \
    "${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 that 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 "[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. | is the pipe character. It 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. && (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.

Note that the US after AvailablePhoneNumbers in the URI is the ISO Country Code.

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 -d "PhoneNumber=${available_number}" \
    "${account_sid}/IncomingPhoneNumbers" \
    -u "${account_sid}:${auth_token}"

After executing this command, you’ll be the happy owner of a new Twilio-provided phone number. If you aren’t, it’s likely because the number may have just been purchased — just re-run the ‘available number’ step and try again.

We’ve made a few changes here when we use curl with the IncomingNumber endpoint:

  • We’re now using the HTTP method POST.
  • We’re POST-ing 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:

curl -X POST -d "Body=Hi there, your new phone number is working." \
    -d "From=${available_number}" -d "To=${your_number}" \
    "${account_sid}/Messages" \
    -u "${account_sid}:${auth_token}"

This command will send a POST request to the Messages endpoint 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: