If you're planning on sending mass text notifications you'll want to make sure that the numbers you're sending to are valid. This post will quickly show how to use the Twilio Lookup API to sanitize your data, checking that:
- Phone numbers are real
- Phone numbers are formatted correctly
- Phone numbers are mobile
Validating and sanitizing phone numbers will mean fewer API errors for sending to non-existent, incorrectly formatted, or landline numbers, giving you greater confidence in your system.
Twilio.org is offering a $500 kickstart credit and additional product discounts for apps that offer public benefits during the COVID-19 crisis. Learn more: https://ahoy.twilio.com/covid19-contact.
Prerequisites for sanitizing phone numbers
- A Twilio account. Get an extra $10 when you upgrade using this link.
- The Twilio Python helper library. Follow instructions to install it here.
The Lookup API does not support bulk requests. If you anticipate a high volume of requests, please contact our sales team for more information and pricing.
Check phone number validity and formatting
Option #1: Normalize phone numbers with national formatting to E.164 and check their validity
This option requires that you know the ISO country code for every phone number, but assuming you have that information you can standardize national formats with parentheses or hyphens to an E.164 formatted number. E.164 is required for many Twilio API phone number inputs.
Copy the following code to a new file, I called mine
from twilio.rest import Client from twilio.base.exceptions import TwilioRestException # Your Account Sid and Auth Token from twilio.com/console # DANGER! Don't commit these tokens to Git. See http://twil.io/secure account_sid = 'ACxxx' auth_token = 'your_auth_token' client = Client(account_sid, auth_token) def format_number(pn, country_code="US"): try: result = client.lookups \ .phone_numbers(pn) \ .fetch(country_code=country_code) return result.phone_number except TwilioRestException as e: print(e.msg) return None print(format_number("(510) 867-5310", country_code="US")) # +15108675310
Valid phone numbers will return the E.164 formatted number. If the function is called with an invalid phone number or mismatched country code, it will return
None and print an exception message:
print(format_number("(510) 867-5310", country_code="GB")) # Unable to fetch record: The requested resource /PhoneNumbers/(510) 867-5310 was not found # None print(format_number("(123) 555-1234", country_code="US")) # Unable to fetch record: The requested resource /PhoneNumbers/(123) 555-1234 was not found # None
def is_valid_number(pn): try: client.lookups.phone_numbers(pn).fetch() return True except TwilioRestException as e: print(e.msg) return False print(is_valid_number("+4402077651182"))
For a valid phone number like the one in the example above, this will return
True. Try it with an invalid phone number like
+12345, the function will return
False and print an exception message:
print(is_valid_number("+4402077651182")) # True print(is_valid_number("+12345")) # Unable to fetch record: The requested resource /PhoneNumbers/+12345 was not found # False
Learn more about formatting international numbers in the docs.
Check for mobile phone number type
If you want to validate numbers and check the phone number line type, use the following code. Note: the carrier lookup shown below costs $0.005 per request. Contact Twilio Sales for pricing if you anticipate a large number of requests.
This code will check the line type of the phone number to see if it is mobile. The possible line types are
def is_mobile(pn): result = client.lookups \ .phone_numbers(pn) \ .fetch(type=['carrier']) return result.carrier['type'] == "mobile" print(is_mobile("+15108675310")) # True
The above code assumes you have a valid phone number. Combine checking for a valid number and checking for a mobile number with something like this:
def is_valid_mobile_number(pn): try: result = client.lookups.phone_numbers(pn).fetch(type=['carrier']) return result.carrier['type'] == "mobile" except TwilioRestException as e: print(e.msg) return False print(is_valid_mobile_number("+15108675310")) # True
Learn more about carrier lookups in the docs.
Next steps after sanitizing phone numbers
The Twilio Lookup API is a great way to validate new inputs or sanitize data you already have. Once you have trust in the data check out more ways to engage with your customers:
Questions? Find me on Twitter. I can't wait to see what you build.