DEV Community

YuppyMans
YuppyMans

Posted on

How to Automate SMS Account Registration: Python & JavaScript Script Breakdown and Number Selection Guide

Imagine you’ve developed a Telegram bot for marketing campaigns. To avoid a spam block caused by an algorithmic error, you need to run a test using 100 accounts. Registering them manually involves physically swapping SIM cards, waiting for SMS codes, and typing them in — all while trying to keep track of which number is linked to which proxy.

Fortunately, there’s a better way. In this article, we’ll explore how to automate SMS code retrieval using a Python script, JavaScript, and a number rental service. If you're only looking for the source code and step-by-step explanations, feel free to skip to the very end of the post.

Why Automation is Crucial

Anti-fraud systems of popular services like Telegram are powered by neural networks. They analyze hundreds of parameters in your requests: if they detect suspicious patterns, your accounts will be banned instantly.

  • Cluster Bans. Telegram notices if 100 accounts share the same IP range or similar device IDs and groups them into a cluster. Once one account is flagged, the rest are purged in a chain reaction.
  • API Trust. If you register accounts only to have them deleted immediately, Telegram stops trusting your App API ID. Eventually, registrations from that ID are blocked before the SMS even arrives. To receive verification codes, you will need two tools: a number rental service and a Python script. The former provides the phone numbers, while the latter handles the account registration itself. Let’s break them down in more detail.

Tools Required for Automation

To automate the process, you need two things: a number rental service to provide the phone numbers and a Python & JavaScript scripts to handle the registration.
1. Number Rental Services
Developers reserve numbers for specific countries and services on these platforms. A number is usually reserved for 10–15 minutes. During this window, you receive the code, enter it into the registration service, and then the number goes inactive.
Many reputable sites use physical SIM cards housed in specialized hardware. Anti-fraud systems recognize these as real users, which helps avoid bans. However, unlike free alternatives, this level of reliability comes at a cost.
2. Python and JavaScript Scripts
Simply receiving a code is not enough: you need to manage user sessions and link each acquired number to a specific proxy server. To avoid doing this manually for hundreds of accounts, we use automation scripts.

  • The Python code communicates with the provider's API to request numbers and initiate the registration process. To do this, it requires an API gateway provided by the rental service. If there are issues with the API — such as incorrect parameters or connectivity drops — the script will fail, requiring manual troubleshooting.
  • The JavaScript code handles the incoming SMS data from the provider instead of the Python script. This makes the architecture faster, more reliable, and serverless. However, this JavaScript component is only necessary if the provider supports Webhooks, which we will discuss in the next section.

The Bottom Line: If your code is perfect but the phone numbers are "flagged" or low-quality, your accounts will be banned in bulk. Conversely, if you have the best SIM cards in the world but still enter codes by hand, you won't be able to scale. These tools only work effectively when used together.

Choosing a Number Provider

To avoid an ID block caused by suspicious numbers, it is essential to understand the criteria for selecting a rental platform. Spoiler: there is no such thing as a free lunch.

Check for Physical SIM Availability

Many rental services use physical SIM cards hosted in hardware devices — but not all of them. If the price is significantly lower than average, or if the numbers are free, you are likely dealing with virtual numbers. Anti-fraud systems often ban these the moment they are entered into the registration field.
While you cannot know for sure if a service uses only physical SIMs, price isn't the only indicator. A reliable workaround is to buy at least a couple of numbers and run them through an HLR checker. Search for "HLR lookup online" and enter the number. If the result shows "VoIP," "Virtual," or "Landline," you’ve found a virtual number and should look for another provider.

Check SMS Delivery Speed

OTP codes have a short lifespan. If a platform's API experiences latency and delivers the code after 2–3 minutes, the script's session may expire. This renders the code invalid, the reservation ends, and the number goes inactive — usually without a refund.
To verify speed, you will need to invest in a few test numbers. Keep in mind that delivery speed fluctuates based on the country, the specific service, the time of day, and current server load. A code for Telegram might arrive instantly in the morning but fail for another service in the evening; testing across different scenarios is essential.

Review the Payment Model

A reputable rental service will not deduct funds if the SMS fails to arrive. Typically, the balance is credited back to your account dashboard. Always check the site’s refund policy or contact support to confirm this.
If a platform charges per attempt rather than per delivered code, find another provider — even if their prices seem lower. Codes often fail due to sudden spikes in demand or anti-fraud updates. If your script attempts to register 100 accounts on a "bad" day, you could lose your entire investment without successfully creating a single account.

Check if the provider supports Webhooks
Most services operate on the Polling principle: your script hits the API every couple of seconds to ask if the code has arrived. If you are registering 1,000 accounts, that translates to about 3,000 requests per minute, which puts a heavy load on your internet bandwidth and CPU. Moreover, if you stop waiting those couple of seconds and start making requests constantly, the SMS service will ban your IP for excessive traffic.
To save their clients' time and resources, some rental services implement Webhooks. In this case, the service itself contacts your script as soon as the SMS reaches the number. As a result, your server doesn't need to keep hundreds of connections open while waiting, and timeouts or bans caused by frequent API requests are completely eliminated.
Webhooks are a "killer feature," but they aren't available everywhere because they are very expensive to implement. To integrate this technology, a service must invest heavily in server capacity. Since these investments might not pay off, many providers choose not to take the risk and stick with polling technology instead.

  • With polling, the load rests on the client's server: the service simply sits and waits for someone to call its API. This technology requires no major investment, and its code doesn't demand lengthy development or ongoing maintenance.
  • With webhooks, the service itself initiates the connection to the client's server. If 10,000 SMS messages arrive at the service in a single second, its system must instantly create 10,000 outgoing requests to various clients without any delay. This is exactly why massive server power is required.

Webhooks serve as a marker that a number provider has invested in the quality of its service. To find out if this technology is available on a website, check the API Documentation section for the following keywords:

  • "Webhooks"
  • "Callback"
  • "Push notifications"

If you find these terms, the technology is integrated. However, services usually mention Webhooks right on the homepage to make sure it catches your eye immediately.

Identify the Provider Category

The SMS service market is divided into three main categories, each with its own specific use cases, pros, and cons. Let's look at them in detail:

Standard Activation Services (e.g., HeroSMS, 5SIM). These platforms use physical SIM cards and provide a clean API. Registration usually requires only an email address, and payments can be made via credit card or cryptocurrency. These are ideal for developers who need to "farm" accounts for testing.

Free Activation Services. These primarily use virtual numbers and rarely offer physical ones. If they do charge, the prices are often ten times lower than standard services. The main issue is that these numbers are overused, meaning spam filters recognize them instantly. They are only suitable for low-security or unpopular services.

Corporate Aggregators (e.g., Twilio, Vonage). These providers offer the highest level of trust from services like Telegram because they use premium physical routes. However, a regular developer cannot simply sign up; they require corporate documentation (KYC) and verification of your messaging intent. These are built for large-scale legitimate businesses.

For testing purposes, standard activation services are the best choice. While they are more expensive than free virtual numbers, they yield a much higher success rate for account creation. Additionally, you won't need to provide the extensive documentation required by corporate aggregators.

Summary of Selection Criteria. A reliable service must:

  1. Use physical SIM cards
  2. Deliver SMS quickly
  3. Offer automatic refunds if the code does not arrive.

Breaking Down the Python & JavaScript Script

We are using JavaScript for the Webhook implementation and Python for the API script, using the Hero-SMS service as our primary example. We chose this platform based on the following criteria:

  • REST API. The API is built on REST principles. It is predictable and well-documented, allowing us to avoid bulky third-party SDKs.
  • Webhooks over Polling. The service utilizes Webhook technology instead of polling. The platform handles the entire load, significantly reducing the strain on the client's server.
  • Physical Numbers, Fast Delivery, and Refunds. The service uses physical SIM cards rather than virtual numbers and provides an automatic refund if the code does not arrive.

Prerequisites:

  • Python 3.7+
  • An API Key from Hero-SMS. You can find it in your profile settings or within the API documentation.
  • The requests library (pip install requests)

Step 1. Setting Up Webhooks

To allow HeroSMS to send data automatically, we need to set up a receiver. Cloudflare Workers is a perfect fit for this — it offers 100,000 requests per day for free. We’ll use a JavaScript script to handle the logic. Follow these instructions:
1. Go to **the Cloudflare Dashboard -> Workers & Pages.
**2. Create a new Worker
and paste the provided JavaScript code. This code transforms your Cloudflare Worker into a perpetually active HTTP server that processes incoming POST requests from Hero-SMS in real-time.

export default {
async fetch(request, env, ctx) {
    const url = new URL(request.url);

    // This Worker will handle requests only on:
    // https://YOUR DOMEN/webhook
    if (url.pathname !== "/webhook") {
      // Return 404 for any other path
      return new Response("Not Found", { status: 404 });
    }

    // Health check endpoint:
    // GET https://YOUR DOMEN/webhook -> "OK"
    if (request.method === "GET") {
      return new Response("OK", { status: 200 });
    }

    // Webhooks are usually sent as POST requests
    if (request.method !== "POST") {
      // Reject any other HTTP method
      return new Response("Method Not Allowed", { status: 405 });
    }

    // Read and parse the request body:
    // - If Content-Type is JSON, parse as JSON
    // - Otherwise, read as plain text
    let body;
    const ct = request.headers.get("content-type") || "";
    try {
      if (ct.includes("application/json")) {
        body = await request.json();
      } else {
        body = await request.text();
      }
    } catch (e) {
      // If parsing fails, log the error info as the body
      body = { parseError: String(e) };
    }

    // Log the incoming webhook to Cloudflare Workers Logs (Tail/Logs tab)
    console.log("WEBHOOK IN", {
      // Timestamp (UTC)
      ts: new Date().toISOString(),
      // Client IP (Cloudflare-provided header)
      ip: request.headers.get("cf-connecting-ip"),
      // User-Agent string
      ua: request.headers.get("user-agent"),
      // All request headers (useful for debugging signatures, auth, etc.)
      headers: Object.fromEntries(request.headers),
      // Parsed body (JSON) or raw text
      body,
    });

    // IMPORTANT: respond quickly with 200 OK so the sender considers delivery successful
    return new Response("OK", { status: 200 });
  },
}; 
Enter fullscreen mode Exit fullscreen mode

3. Save and Deploy. Copy the generated URL (for example, https://sms-receiver.username.workers.dev/webhook). Important: Ensure the URL ends with /webhook as defined in the script logic.
4. Add this address to your HeroSMS account under the Personal Information (or Profile) section.

Step 2. Preparing Identifiers for the Python Script

To ensure the script knows exactly which number to request, we use short identifiers. For example, tg stands for Telegram, and 6 represents a specific country code. There is no need to guess these values — the Hero-SMS API provides dedicated endpoints for this:

  • /getCountries — returns a complete list of available countries and their respective codes.
  • /getServices — displays a list of all platforms available for number rentals. You only need to call these methods once to get the up-to-date reference data for your script configuration. Since these are standard GET requests, you can simply paste the link into your browser's address bar, replacing the placeholder with your actual API key:

https://hero-sms.com/api/getCountries?api_key=YOUR_API_KEY

The browser will display a text file containing all available countries/services along with their shorthand identifiers.

To get your API key, register on the Hero-SMS website and copy it from the API Settings or the Documentation section.

Step 3. Breaking Down the Python Code

We inform the server which service we need a number for and which country to select.

import requests

# Your API Key from the Hero-SMS dashboard
API_KEY = 'YOUR_API_KEY_HERE'
BASE_URL = 'https://hero-sms.com/api'

def order_number(service='tg', country='6'):
    try:
        # Sending a request to purchase a number
        response = requests.get(f"{BASE_URL}/getOrder", params={
            'api_key': API_KEY,
            'service': service,
            'country': country
        })
        data = response.json()

        if 'error' in data:
            print(f"Order Error: {data['error']}")
            return

        order_id = data['id']
        phone_number = data['number']

        print(f"Number received: {phone_number}")
        print(f"Order ID: {order_id}")
        print("Instruction: Enter the number into the service. The code will appear in Cloudflare logs.")

        return order_id

    except Exception as e:
        print(f"API Connection Error: {e}")

# Execute the function
order_number(service='tg', country='6')
Enter fullscreen mode Exit fullscreen mode

We send a GET request to the /getOrder endpoint. The server reserves a real SIM card for us and returns a unique order_id.

Once the script displays the phone number in the console, the automation pauses. Now, you must copy this number, paste it into the registration field of your chosen service, and click "Request Code." Only after this step will the SMS be sent to the SIM card, allowing the Cloudflare Worker to receive and log the code automatically. This process can also be further automated using a separate script.

Conclusion

To avoid account bans during testing and eliminate the need for manual registration, automating the process is essential. This requires two key components: a reliable number provider and a Python & JavaScript script to interact with their API.


When choosing a provider, you must verify that they offer physical SIM cards, ensure they deliver codes quickly, and confirm the stability of their API. The overall performance of the script described in this article directly depends on these factors.

The HeroSMS service fits all these criteria. Visit their website, review the documentation, and start automating your registrations via their API today.

Ready-to-use code JavaScript

export default {
async fetch(request, env, ctx) {
    const url = new URL(request.url);

    // This Worker will handle requests only on:
    // https://YOUR DOMEN/webhook
    if (url.pathname !== "/webhook") {
      // Return 404 for any other path
      return new Response("Not Found", { status: 404 });
    }

    // Health check endpoint:
    // GET https://YOUR DOMEN/webhook -> "OK"
    if (request.method === "GET") {
      return new Response("OK", { status: 200 });
    }

    // Webhooks are usually sent as POST requests
    if (request.method !== "POST") {
      // Reject any other HTTP method
      return new Response("Method Not Allowed", { status: 405 });
    }

    // Read and parse the request body:
    // - If Content-Type is JSON, parse as JSON
    // - Otherwise, read as plain text
    let body;
    const ct = request.headers.get("content-type") || "";
    try {
      if (ct.includes("application/json")) {
        body = await request.json();
      } else {
        body = await request.text();
      }
    } catch (e) {
      // If parsing fails, log the error info as the body
      body = { parseError: String(e) };
    }

    // Log the incoming webhook to Cloudflare Workers Logs (Tail/Logs tab)
    console.log("WEBHOOK IN", {
      // Timestamp (UTC)
      ts: new Date().toISOString(),
      // Client IP (Cloudflare-provided header)
      ip: request.headers.get("cf-connecting-ip"),
      // User-Agent string
      ua: request.headers.get("user-agent"),
      // All request headers (useful for debugging signatures, auth, etc.)
      headers: Object.fromEntries(request.headers),
      // Parsed body (JSON) or raw text
      body,
    });

    // IMPORTANT: respond quickly with 200 OK so the sender considers delivery successful
    return new Response("OK", { status: 200 });
  },
};

Enter fullscreen mode Exit fullscreen mode

Ready-to-use code Python

import requests

# Your API Key from the Hero-SMS dashboard
API_KEY = 'YOUR_API_KEY_HERE'
BASE_URL = 'https://hero-sms.com/api'

def order_number(service='tg', country='6'):
    try:
        # Sending a request to purchase a number
        response = requests.get(f"{BASE_URL}/getOrder", params={
            'api_key': API_KEY,
            'service': service,
            'country': country
        })
        data = response.json()

        if 'error' in data:
            print(f"Order Error: {data['error']}")
            return

        order_id = data['id']
        phone_number = data['number']

        print(f"Number received: {phone_number}")
        print(f"Order ID: {order_id}")
        print("Instruction: Enter the number into the service. The code will appear in Cloudflare logs.")

        return order_id

    except Exception as e:
        print(f"API Connection Error: {e}")

# Execute the function
order_number(service='tg', country='6')
Enter fullscreen mode Exit fullscreen mode

Top comments (0)