How to Retrieve a Phone Number's SMS Pumping Score in Rust

October 14, 2026
Written by
Reviewed by

How to Retrieve a Phone Number's SMS Pumping Score in Rust

SMS Pumping Fraud is:

when fraudsters take advantage of a phone number input field to receive a one-time passcode, an app download link, or anything else via SMS. The messages are sent to a range of numbers controlled by a specific mobile network operator (MNO) and the fraudsters get a share of the generated revenue.

Two ways to know if you're the victim of SMS Pumping Fraud, are seeing:

  • A raft of messages sent to a block of adjacent numbers (e.g., +1111111110, +1111111111, and +1111111112, etc); numbers all controlled by the same MNO (Mobile Network Operator)
  • Incomplete verification cycles if you're sending SMS for a one-time passcode (OTP)

Unfortunately, SMS Pumping Fraud is not just a verification problem! Targets also include lead generation forms, transactional notifications, marketing campaigns, and inbound chatbot endpoints.

Because SMS remains a popular channel across various industries, it's crucial to protect both your organization and customers from this growing threat.

There are several ways to do so, but one of the simplest ways is to check a number's SMS Pumping Risk Score (a value between 0 and 100) before sending to it, and avoid sending to that number if the risk is too high. Twilio makes this relatively trivial through the Lookup v2 API's Line Type Intelligence functionality.

The score is based on a proprietary risk model built from Twilio's network data, including signals from Verify Fraud Guard and risky carriers, unusual SMS traffic patterns, and low conversion rates.

In this short tutorial, you're going to learn how to retrieve a number's SMS Pumping Risk Score, along with other helpful information, in Rust.

Canadian phone numbers don't return carrier information. Twilio doesn't recommend using SMS Pumping Risk Score for US or Canadian phone numbers, as these regions are generally not targeted by SMS pumping fraud.

Prerequisites

To follow along with this tutorial, you'll need the following:

  • A Twilio account (either free or paid). Create one now if you don't have one already.
  • A mobile/cell phone number that you want to check
  • Rust and Cargo installed
  • Your preferred Rust editor or IDE, such as Neovim or Rust Rover
  • Some prior experience with Rust and the command-line would be helpful

Create the Rust project

The first thing to do is to create a new binary Rust project and change into the new project directory, by running the following commands:

cargo new get-sms-pumping-risk-score --bin
cd get-sms-pumping-risk-score

Add the required crates

Next up, naturally, is to add the crates that the app will need. There aren't many, just the following:

Crate

Description

These simplify setting and retrieving the environment variables that the app will need. Doing this keeps credentials and configuration data out of the Rust code.

This simplifies interacting with Twilio's Lookup v2 API.

These simplify deserialising the response from the Lookup API requests, making it easier to work with them.

This simplifies writing async code.

To add them, run the following command:

cargo add dotenvy rustlio serde serde_json tokio --features serde/derive

Set the required environment variables

The application makes use of three environment variables. These are your Twilio Account SID and Auth Token, and a mobile/cell phone number or two that you want to retrieve the SMS Pumping Risk Score for.

To set them, create a new file named .env and in that file paste the code below.

TWILIO_ACCOUNT_SID="<TWILIO_ACCOUNT_SID>"
TWILIO_AUTH_TOKEN="<TWILIO_AUTH_TOKEN>"

Next, log in to your Twilio Console, then, from the Account Info panel of the Account Dashboard, copy the Account SID and Auth Token.

A dark-themed user interface displaying API credentials and quick action buttons in a workbench dashboard.

After that, paste the values into .env in place of <TWILIO_ACCOUNT_SID> and <TWILIO_AUTH_TOKEN>, respectively.

Write the Rust code

Now, you will get to the core of the tutorial and write the application's Rust code. To do that, replace the code in src/main.rs with the following:

use reqwest::Client;
use rustlio::lookup;
use rustlio::lookup::DataPackage;
use std::env;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    match dotenvy::dotenv() {
        Ok(_) => println!("Environment variables were loaded"),
        Err(e) => println!("Environment variables were NOT loaded because: {e}"),
    };

    let phone_number = "<<YOUR PHONE NUMBER>>";
    let data = lookup::lookup_phone_data(
        phone_number,
        &[DataPackage::SmsPumpingRiskScore],
        &Client::new(),
        &env::var("TWILIO_ACCOUNT_SID").unwrap(),
        &env::var("TWILIO_AUTH_TOKEN").unwrap(),
    )
    .await
    .unwrap_or_default();
    let sms_pumping_risk_sccore = data
        .sms_pumping_risk
        .ok_or("SMS Pumping Risk Score data is not available for {phone_number}")?;
    println!(
        "SMS Pumping Risk Score for {phone_number}: {:?}",
        sms_pumping_risk_sccore
    );

    Ok(())
}

Now, replace <<YOUR PHONE NUMBER>> with the phone number that you want to check.

The code looks up the details of the phone number. It prints out the SMS Pumping Risk Score data to the terminal if available. Otherwise, it prints an error stating that no SMS Pumping Risk Score data was available.

Test that the application works

At this point, we're ready to use the code. To do that, back in the terminal, run the command below.

cargo run

You should see output similar to the following printed to the terminal:

SMS Pumping Risk Score for <<YOUR PHONE NUMBER>>: SmsPumpingRiskScore { carrier_risk_category: Some("low"), number_blocked: Some(false), number_blocked_date: None, number_blocked_last_3_months: None, sms_pumping_risk_score: 2, error_code: None }

Here's what the properties represent:

Property

Description

CarrierRiskCategory

The risk category of the carrier based on its score. Available values are high, moderate, mild, and low.

NumberBlocked

Indicates whether the phone number is currently blocked for receiving malicious SMS pumping traffic by Verify Fraud Guard.

NumberBlockedDate

The most recent date the phone number was blocked by Verify Fraud Guard. This is set to null if the phone number has never been blocked or processed by Verify Fraud Guard.

NumberBlockedLast3Months

Indicates whether the phone number has been blocked by Verify Fraud Guard in the last three months. It's set to null if the phone number has never been processed by Verify Fraud Guard.

SmsPumpingRiskScore

The risk score for the phone number, calculated from patterns in messaging traffic. Ranges from 0 (no risk) to 100 (high risk).

ErrorCode

The error code, if any, associated with your request.

Twilio provides the following guidelines when using a phone number's risk score:

Risk Score

Risk Level

Guideline

0 - 60

Low

Send messages as requested.

60 - 75

Mild

Ask the requester to re-submit the request or add friction prior to sending messages.

75 - 90

Moderate

Treat the request as suspicious. Add friction prior to sending messages or consider not sending messages.

90 - 100

High

Don't send messages.

That's how to retrieve a phone number's SMS Pumping Score in Rust

Now that you know how to retrieve a phone number's SMS Pumping Risk Score and related information, you're better able to protect both your organization and your customers from SMS Pumping Fraud.

As you build your implementation, make sure that you:

I can't wait to see what you build!

Matthew Setter is a PHP and Go Editor in the Twilio Voices team. He’s also the author of Mezzio Essentials and Deploy with Docker Compose. You can find him at msetter@twilio.com. He's also on LinkedIn and GitHub.