Building SMS Notifications into Your App: A Developer's Guide
Developer Guides Tutorials #SMS API #Developer Guide #Integration #Code Examples #Notifications

Building SMS Notifications into Your App: A Developer's Guide

By: Jayson Presto
Published: February 06, 2026

Learn how to integrate SMS notifications into your application using IPROG SMS. Complete guide with code examples in Ruby, PHP, Python, JavaScript, and more.

Building SMS Notifications into Your App: A Developer's Guide


SMS notifications are one of the most effective ways to reach users directly. With a 98% open rate and near-instant delivery, SMS is perfect for critical alerts, OTP codes, appointment reminders, and transactional notifications. In this comprehensive guide, we'll walk you through integrating SMS notifications into your application using IPROG SMS.


Why SMS Notifications?

Before diving into the technical details, let's understand why SMS notifications are essential for modern applications:

  • High Open Rates: SMS messages have a 98% open rate compared to 20-30% for email
  • Instant Delivery: Messages are typically delivered within seconds
  • Universal Reach: Works on all mobile devices, even basic feature phones
  • User Trust: Users expect important notifications via SMS
  • No App Required: Works without users installing your app

Getting Started with IPROG SMS


Prerequisites

Before you begin, you'll need:

  • An IPROG SMS account (sign up at iprogsms.com)
  • SMS credits loaded into your account
  • Your API token (found in your account dashboard)
  • Basic knowledge of HTTP requests and your preferred programming language

Getting Your API Token

Your API token is your authentication key for all API requests. Here's how to get it:

  1. Log in to your IPROG SMS account
  2. Navigate to your account settings or dashboard
  3. Find your API token (it will look like: abc123def456...)
  4. Keep this token secure and never commit it to version control

Security Best Practice:
Store your API token as an environment variable, not in your source code.


API Endpoints Overview

IPROG SMS provides several endpoints for different use cases:


Core SMS Endpoints

  • POST /api/v1/sms_messages - Send a single SMS message
  • POST /api/v1/sms_messages/send_bulk - Send SMS to multiple recipients
  • GET /api/v1/sms_messages/status - Check the status of a sent message
  • GET /api/v1/accounts/sms_credits - Check your account balance

Built-in Feature Endpoints

  • POST /api/v1/otp/send_otp - Send OTP (One-Time Password) with automatic generation and expiration
  • POST /api/v1/otp/verify_otp - Verify an OTP code
  • POST /api/v1/message-reminders - Schedule SMS reminders for future delivery
  • GET /api/v1/message-reminders/:id - View a scheduled reminder
  • PATCH /api/v1/message-reminders/:id - Update a scheduled reminder
  • DELETE /api/v1/message-reminders/:id - Delete a scheduled reminder

Base URL: https://iprogsms.com


Sending Your First SMS


Single SMS Request

The simplest way to send an SMS is using a POST request to the /api/v1/sms_messages endpoint. Here's what you need:

  • api_token: Your API authentication token
  • phone_number: Recipient's phone number (Philippines format: 639171234567)
  • message: The SMS message content

Phone Number Format

Phone numbers must be in international format without the plus sign:

  • ✅ Correct: 639171234567
  • ❌ Wrong: +639171234567
  • ❌ Wrong: 09171234567
  • ❌ Wrong: 9171234567

The format is: 63 (country code) + 9 (mobile prefix) + 10-digit number


Code Examples


Ruby Example

require 'net/http'
require 'uri'
require 'json'

# Define the API endpoint
uri = URI('https://iprogsms.com/api/v1/sms_messages')

# Set up the HTTP request
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.path, { 'Content-Type' => 'application/json' })

# Request body
request.body = {
  api_token: ENV['IPROG_SMS_API_TOKEN'],
  phone_number: '639171071234',
  message: 'Hello! This is a test message from IPROG SMS.'
}.to_json

# Send the request
response = http.request(request)
puts JSON.parse(response.body)


PHP Example

<?php
$url = 'https://iprogsms.com/api/v1/sms_messages/';

$data = [
    'api_token' => getenv('IPROG_SMS_API_TOKEN'),
    'message' => 'Hello! This is a test message from IPROG SMS.',
    'phone_number' => '639171071234'
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/x-www-form-urlencoded'
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo $response;
?>


Python Example

import requests
import os

url = 'https://iprogsms.com/api/v1/sms_messages'

data = {
    'api_token': os.getenv('IPROG_SMS_API_TOKEN'),
    'phone_number': '639171071234',
    'message': 'Hello! This is a test message from IPROG SMS.'
}

response = requests.post(url, json=data)
print(response.json())


JavaScript/Node.js Example

const axios = require('axios');

const sendSMS = async () => {
  try {
    const response = await axios.post(
      'https://iprogsms.com/api/v1/sms_messages',
      {
        api_token: process.env.IPROG_SMS_API_TOKEN,
        phone_number: '639171071234',
        message: 'Hello! This is a test message from IPROG SMS.'
      },
      {
        headers: {
          'Content-Type': 'application/json'
        }
      }
    );
    
    console.log('Success:', response.data);
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
  }
};

sendSMS();


cURL Example

curl -X POST "https://iprogsms.com/api/v1/sms_messages"      -H "Content-Type: application/json"      -d '{
       "api_token": "your_api_token_here",
       "phone_number": "639171071234",
       "message": "Hello! This is a test message from IPROG SMS."
     }'


Understanding the Response

When you send an SMS, you'll receive a JSON response. Here's what a successful response looks like:

{
  "status": 200,
  "message": "SMS successfully queued for delivery.",
  "message_id": "iSms-abc123",
  "message_status_link": "https://iprogsms.com/api/v1/sms_messages/status?api_token=12345&message_id=iSms-abc123",
  "message_status_request_mode": "GET",
  "sms_rate": 1
}


Response Fields:

  • status: HTTP status code (200 = success)
  • message: Human-readable status message
  • message_id: Unique identifier for tracking this message
  • message_status_link: URL to check message status
  • sms_rate: Number of SMS credits used. Messages are split into multiple parts based on character encoding: 
    • GSM-7 (standard characters): 160 characters per SMS (153 characters per segment for multi-part messages)
    • Unicode (emojis & special characters): 70 characters per SMS (67 characters per segment for multi-part messages). Using emojis reduces the character count per SMS segment.

Error Handling

It's crucial to handle errors gracefully in your application. Here are common error responses and how to handle them:


Invalid API Token

{
  "status": 500,
  "message": "Invalid api token or no load balance"
}


Solution:
Verify your API token is correct and your account has sufficient SMS credits.


Missing Required Parameters

{
  "status": 500,
  "message": "API Token, phone number and message are required."
}


Solution:
Ensure all required parameters (api_token, phone_number, message) are included in your request.


Rate Limit Exceeded

Note: Rate limiting is currently applied to the web interface (sending SMS through the website), not the API endpoints. API users can send messages without rate limit restrictions.


If you're using the web interface and encounter rate limit errors, you'll see a message like:

{
  "status": 500,
  "message": "You've hit the limit of 3 requests per minute. For unlimited access, explore our pricing plans."
}


For API users:
You don't need to worry about rate limits when using the API. However, it's still good practice to implement request throttling in your application to avoid overwhelming your system or the SMS service.


Error Handling Example (Python)

import requests
import os
import time

def send_sms_with_retry(phone_number, message, max_retries=3):
    url = 'https://iprogsms.com/api/v1/sms_messages'
    api_token = os.getenv('IPROG_SMS_API_TOKEN')
    
    data = {
        'api_token': api_token,
        'phone_number': phone_number,
        'message': message
    }
    
    for attempt in range(max_retries):
        try:
            response = requests.post(url, json=data, timeout=10)
            result = response.json()
            
            if result.get('status') == 200:
                return {
                    'success': True,
                    'message_id': result.get('message_id'),
                    'data': result
                }
            else:
                # Check if it's a rate limit error
                if 'limit' in result.get('message', '').lower():
                    wait_time = (attempt + 1) * 2  # Exponential backoff
                    print(f"Rate limit hit. Waiting {wait_time} seconds...")
                    time.sleep(wait_time)
                    continue
                
                return {
                    'success': False,
                    'error': result.get('message', 'Unknown error')
                }
                
        except requests.exceptions.Timeout:
            print(f"Request timeout. Attempt {attempt + 1}/{max_retries}")
            if attempt < max_retries - 1:
                time.sleep(2)
                continue
        except requests.exceptions.RequestException as e:
            return {
                'success': False,
                'error': f'Network error: {str(e)}'
            }
    
    return {
        'success': False,
        'error': 'Max retries exceeded'
    }

# Usage
result = send_sms_with_retry('639171071234', 'Test message')
if result['success']:
    print(f"Message sent! ID: {result['message_id']}")
else:
    print(f"Failed: {result['error']}")


Sending Bulk SMS

For sending SMS to multiple recipients, use the bulk endpoint. This is more efficient than sending individual requests.


Bulk SMS Request

POST /api/v1/sms_messages/send_bulk


Parameters:

  • api_token: Your API token
  • phone_number: Comma-separated list of phone numbers (e.g., 639171234567,639171234568,639171234569)
  • message: The message to send to all recipients

Bulk SMS Example (Python)

import requests
import os

def send_bulk_sms(phone_numbers, message):
    url = 'https://iprogsms.com/api/v1/sms_messages/send_bulk'
    
    # Convert list to comma-separated string
    phone_numbers_str = ','.join(phone_numbers)
    
    data = {
        'api_token': os.getenv('IPROG_SMS_API_TOKEN'),
        'phone_number': phone_numbers_str,
        'message': message
    }
    
    response = requests.post(url, json=data)
    return response.json()

# Usage
recipients = [
    '639171234567',
    '639171234568',
    '639171234569'
]

result = send_bulk_sms(recipients, 'Bulk message to all recipients')
print(result)


Bulk Response:

{
  "status": 200,
  "message": "Your bulk SMS messages have been successfully added to the queue...",
  "message_ids": "iSms-abc123,iSms-def456,iSms-ghi789",
  "sms_rates": "1,1,1",
  "message_status_link": "https://iprogsms.com/api/v1/sms_messages/status?...",
  "message_status_request_mode": "GET"
}


Checking Message Status

After sending an SMS, you can check its delivery status using the message_id returned in the response.


Status Endpoint

GET /api/v1/sms_messages/status?api_token=YOUR_TOKEN&message_id=MESSAGE_ID


Status Check Example (Python)

import requests
import os
import time

def check_message_status(message_id):
    url = 'https://iprogsms.com/api/v1/sms_messages/status'
    
    params = {
        'api_token': os.getenv('IPROG_SMS_API_TOKEN'),
        'message_id': message_id
    }
    
    response = requests.get(url, params=params)
    return response.json()

# Usage
message_id = 'iSms-abc123'  # From the send response
status = check_message_status(message_id)
print(f"Status: {status.get('message_status')}")
print(f"SMS Count: {status.get('sms_count')}")


Possible Status Values:

  • pending: Message is queued and waiting to be sent
  • completed: Message was successfully delivered
  • failed: Message delivery failed

Checking Account Balance

Before sending messages, it's good practice to check your account balance to ensure you have sufficient credits.


Balance Check Endpoint

GET /api/v1/accounts/sms_credits?api_token=YOUR_TOKEN


Balance Check Example (Python)

import requests
import os

def check_balance():
    url = 'https://iprogsms.com/api/v1/accounts/sms_credits'
    
    params = {
        'api_token': os.getenv('IPROG_SMS_API_TOKEN')
    }
    
    response = requests.get(url, params=params)
    result = response.json()
    
    if result.get('status') == 'success':
        balance = result.get('data', {}).get('load_balance', 0)
        print(f"Current balance: {balance} SMS credits")
        return balance
    else:
        print(f"Error: {result.get('message')}")
        return None

# Usage
balance = check_balance()
if balance and balance < 10:
    print("Warning: Low balance! Consider topping up.")


Best Practices


1. Store Credentials Securely

Never hardcode your API token. Use environment variables or a secure configuration management system:

# .env file (never commit this!)
IPROG_SMS_API_TOKEN=your_actual_token_here

# In your code
import os
api_token = os.getenv('IPROG_SMS_API_TOKEN')


2. Validate Phone Numbers

Always validate phone numbers before sending:

import re

def validate_philippine_phone(phone_number):
    # Remove any spaces, dashes, or plus signs
    cleaned = re.sub(r'[ -+]', '', phone_number)
    
    # Check if it starts with 63 and has 12 digits total
    pattern = r'^63[9]d{9}$'
    return bool(re.match(pattern, cleaned))

# Usage
phone = '639171234567'
if validate_philippine_phone(phone):
    # Send SMS
    pass
else:
    print("Invalid phone number format")


3. Implement Retry Logic

Network issues can cause temporary failures. Implement retry logic with exponential backoff:

import time
import random

def send_with_retry(url, data, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = requests.post(url, json=data, timeout=10)
            if response.status_code == 200:
                return response.json()
        except requests.exceptions.RequestException:
            if attempt < max_retries - 1:
                # Exponential backoff with jitter
                wait_time = (2 ** attempt) + random.uniform(0, 1)
                time.sleep(wait_time)
            else:
                raise
    return None


4. Handle Message Length

SMS messages have different character limits based on encoding:

  • GSM-7 (standard characters): 160 characters per SMS, 153 characters per segment for multi-part messages
  • Unicode (emojis & special characters): 70 characters per SMS, 67 characters per segment for multi-part messages

Important:
Using emojis or special Unicode characters reduces the character count per SMS segment from 153 to 67 characters, which means your message will use more SMS credits.

import re

def calculate_sms_count(message):
    # Check if message contains Unicode characters (emojis, special chars)
    has_unicode = bool(re.search(r'[^-]', message))
    
    if has_unicode:
        # Unicode encoding: 70 chars per SMS, 67 per segment for multi-part
        if len(message) <= 70:
            return 1
        else:
            return 1 + ((len(message) - 70) // 67) + (1 if (len(message) - 70) % 67 > 0 else 0)
    else:
        # GSM-7 encoding: 160 chars per SMS, 153 per segment for multi-part
        if len(message) <= 160:
            return 1
        else:
            return 1 + ((len(message) - 160) // 153) + (1 if (len(message) - 160) % 153 > 0 else 0)

# Usage
message1 = "Your standard message here..."  # GSM-7
message2 = "Your message with emoji 🎉 here..."  # Unicode

sms_count1 = calculate_sms_count(message1)
sms_count2 = calculate_sms_count(message2)

print(f"Standard message: {sms_count1} SMS credit(s)")
print(f"Message with emoji: {sms_count2} SMS credit(s)")


5. Use Queues for High Volume

For high-volume sending, implement a queue system to avoid rate limits:

from queue import Queue
import threading

sms_queue = Queue()

def sms_worker():
    while True:
        item = sms_queue.get()
        if item is None:
            break
        phone_number, message = item
        send_sms(phone_number, message)
        sms_queue.task_done()
        time.sleep(1)  # Rate limiting

# Start worker threads
for _ in range(3):  # 3 concurrent workers
    threading.Thread(target=sms_worker, daemon=True).start()

# Add messages to queue
sms_queue.put(('639171234567', 'Message 1'))
sms_queue.put(('639171234568', 'Message 2'))


6. Log All SMS Activity

Keep logs of all SMS sent for debugging and auditing:

import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def send_sms_with_logging(phone_number, message):
    try:
        result = send_sms(phone_number, message)
        logger.info(f"SMS sent successfully. ID: {result.get('message_id')}, To: {phone_number}")
        return result
    except Exception as e:
        logger.error(f"Failed to send SMS to {phone_number}: {str(e)}")
        raise


Common Use Cases


1. OTP (One-Time Password) Verification

IPROG SMS provides a built-in OTP API that handles OTP generation, sending, and verification automatically. This is much easier than implementing it manually!


Send OTP

Use the dedicated OTP endpoint to send a verification code:

POST /api/v1/otp/send_otp


Parameters:

  • api_token: Your API token
  • phone_number: Recipient's phone number
  • message: (optional) Custom message. Use :otp placeholder for the code. Default: "Your OTP code is :otp. It is valid for 5 minutes. Do not share this code with anyone."
  • code_length: (optional) Length of OTP code (default: 6)

Example (Python):

import requests
import os

def send_otp(phone_number, custom_message=None):
    url = 'https://iprogsms.com/api/v1/otp/send_otp'
    
    data = {
        'api_token': os.getenv('IPROG_SMS_API_TOKEN'),
        'phone_number': phone_number
    }
    
    if custom_message:
        data['message'] = custom_message
    
    response = requests.post(url, json=data)
    return response.json()

# Usage
result = send_otp('639171234567')
if result.get('status') == 'success':
    print(f"OTP sent! Code: {result['data']['otp_code']}")
    print(f"Expires at: {result['data']['otp_code_expires_at']}")


Verify OTP

Verify the OTP code entered by the user:

POST /api/v1/otp/verify_otp


Parameters:

  • api_token: Your API token
  • phone_number: Recipient's phone number
  • otp: The OTP code to verify

Example (Python):

def verify_otp(phone_number, otp_code):
    url = 'https://iprogsms.com/api/v1/otp/verify_otp'
    
    data = {
        'api_token': os.getenv('IPROG_SMS_API_TOKEN'),
        'phone_number': phone_number,
        'otp': otp_code
    }
    
    response = requests.post(url, json=data)
    return response.json()

# Usage
result = verify_otp('639171234567', '123456')
if result.get('status') == 'success':
    print("OTP verified successfully!")
else:
    print(f"Verification failed: {result.get('message')}")


Benefits of using the built-in OTP API:

  • Automatic OTP generation (6 digits by default, configurable)
  • Built-in expiration handling (5 minutes default)
  • Automatic SMS sending with proper formatting
  • Secure verification with expiration checks
  • No need to store OTPs in your database

2. Scheduled Message Reminders

IPROG SMS provides a built-in reminder API that automatically sends SMS messages at scheduled times. No need to set up cron jobs or task schedulers!


Create a Reminder

Schedule a message to be sent at a specific date and time:

POST /api/v1/message-reminders


Parameters:

  • api_token: Your API token
  • phone_number: Recipient's phone number
  • message: The message to send
  • scheduled_at: Date and time in format: YYYY-MM-DDTHH:MM (e.g., 2024-02-15T14:30)

Example (Python):

from datetime import datetime, timedelta

def create_reminder(phone_number, message, scheduled_at):
    url = 'https://iprogsms.com/api/v1/message-reminders'
    
    data = {
        'api_token': os.getenv('IPROG_SMS_API_TOKEN'),
        'phone_number': phone_number,
        'message': message,
        'scheduled_at': scheduled_at.strftime('%Y-%m-%dT%H:%M')
    }
    
    response = requests.post(url, json=data)
    return response.json()

# Schedule reminder 24 hours before appointment
appointment = datetime(2024, 2, 15, 14, 30)
reminder_time = appointment - timedelta(hours=24)

result = create_reminder(
    '639171234567',
    'Reminder: You have an appointment tomorrow at 2:30 PM.',
    reminder_time
)

if result.get('status') == 'success':
    print(f"Reminder scheduled: {result['message']}")


Update or Delete Reminders

You can also update or delete scheduled reminders:

  • GET /api/v1/message-reminders/:id - View a reminder
  • PATCH /api/v1/message-reminders/:id - Update a reminder
  • DELETE /api/v1/message-reminders/:id - Delete a reminder

Benefits of using the built-in Reminder API:

  • No need to set up cron jobs or task schedulers
  • Automatic message sending at scheduled times
  • Easy to update or cancel reminders
  • Reliable delivery without managing background jobs

3. Transactional Notifications

def send_transaction_notification(phone_number, transaction_type, amount, reference):
    if transaction_type == 'payment_received':
        message = f"Payment of ₱{amount:,.2f} received. Reference: {reference}"
    elif transaction_type == 'order_shipped':
        message = f"Your order {reference} has been shipped!"
    else:
        message = f"Transaction update: {transaction_type}. Reference: {reference}"
    
    return send_sms(phone_number, message)


Rate Limits and Quotas

Important: Rate limiting is currently only applied to the web interface (sending SMS through the website), not to API endpoints. API users can send messages without rate limit restrictions.


Web Interface Rate Limits

If you're using the web interface to send SMS, you may encounter rate limits:

  • Per-minute limit: 3 requests per minute for non-premium accounts
  • Daily limit: Varies based on account type (typically 20-1000 messages per day)

API Usage

API endpoints do not have rate limits enforced. However, we still recommend:

  • Implementing request throttling in your application to avoid overwhelming your system
  • Using bulk sending endpoints when sending to multiple recipients (more efficient than individual requests)
  • Monitoring your API usage and account balance
  • Implementing proper error handling and retry logic

Testing Your Integration

Before going live, thoroughly test your SMS integration:

  1. Test with your own phone number first
  2. Test error scenarios: Invalid tokens, insufficient balance, invalid phone numbers
  3. Test rate limiting: Send multiple messages quickly to see how your app handles limits
  4. Test message length: Try messages of different lengths (short, exactly 160 chars, long multi-part)
  5. Monitor delivery: Check message status to ensure delivery

Troubleshooting


Messages Not Sending

  • Check your API token is correct
  • Verify you have sufficient SMS credits
  • Ensure phone numbers are in correct format (639XXXXXXXXX)
  • Check for rate limit errors
  • Review error messages in API responses

Messages Delayed

  • SMS delivery is typically instant but can take up to a few minutes during peak times
  • Check message status using the status endpoint
  • Verify the recipient's phone is powered on and has signal

High Failure Rate

  • Verify phone number formats are correct
  • Check if recipient numbers are valid and active
  • Review message content for any restricted content
  • Contact support if issues persist

Conclusion

Integrating SMS notifications into your application is straightforward with IPROG SMS. By following this guide, you should be able to:

  • Send single and bulk SMS messages
  • Check message delivery status
  • Handle errors gracefully
  • Implement best practices for production use

Remember to always:

  • Keep your API token secure
  • Validate phone numbers before sending
  • Implement proper error handling and retry logic
  • Monitor your SMS usage and account balance
  • Test thoroughly before deploying to production

For additional support, documentation, and code examples, visit our website or check out our code examples.


Happy coding! 🚀

Comments (0)

No comments yet. Be the first to comment!

Please sign in to leave a comment.

Quick Access

Sender Name Networks Daily Limit
iprogSMS
Supported
Globe / TM / DITO / GOMO
Not Supported
Smart / TNT

Download IPROG SMS Mobile App