HLR & Operator Lookup
Query phone number information including network operator, validity, portability status, and pricing before sending SMS messages.
What is HLR?
HLR (Home Location Register) is a database that contains information about mobile phone subscribers on a network. HLR lookup allows you to:
- ✅ Verify if a phone number is valid and active
- ✅ Identify the mobile network operator
- ✅ Check if a number has been ported to another operator
- ✅ Get pricing information for sending to that number
- ✅ Clean your recipient lists before campaigns
HLR Request
Perform HLR lookup for one or multiple phone numbers.
Endpoint:
GET https://www.lightsms.com/external/get/hlr.php
Required Parameters:
| Parameter | Type | Description |
|---|---|---|
login | string | Your LightSMS login |
signature | string | MD5 signature |
phone | string | Phone number(s) - comma-separated (max 100) |
timestamp | integer | UTC timestamp (valid for 10 seconds) |
Optional Parameters:
| Parameter | Type | Description |
|---|---|---|
return | string | Response format: json or xml |
Example Requests
Single Number Lookup
curl "https://www.lightsms.com/external/get/hlr.php?login=YourLogin&phone=37061234567&signature=generated_signature×tamp=1732809600&return=json"
Multiple Numbers Lookup
curl "https://www.lightsms.com/external/get/hlr.php?login=YourLogin&phone=37061234567,37062345678,37063456789&signature=generated_signature×tamp=1732809600&return=json"
Operator Lookup
Get detailed information about a phone number's network operator and pricing.
Endpoint:
GET https://www.lightsms.com/external/get/operator.php
Required Parameters:
| Parameter | Type | Description |
|---|---|---|
login | string | Your LightSMS login |
signature | string | MD5 signature |
phone | string | Phone number to query |
timestamp | integer | UTC timestamp (valid for 10 seconds) |
Optional Parameters:
| Parameter | Type | Description |
|---|---|---|
return | string | Response format: json or xml |
text | string | SMS text (for accurate pricing based on message length) |
Operator Lookup Response
Example Request:
curl "https://www.lightsms.com/external/get/operator.php?login=YourLogin&signature=generated_signature×tamp=1732809600&return=json&phone=37061234567"
Response (JSON):
{
"currency": "EUR",
"error": 0,
"mcc": "246",
"mnc": "02",
"ok": true,
"operator": "Tele2 Lithuania",
"phone": "37061234567",
"ported": 0,
"price": 0.012,
"regionCode": 0,
"timeZone": 2
}
Response Fields
| Field | Type | Description |
|---|---|---|
currency | string | Currency code (EUR, USD, etc.) |
error | integer | Error code (0 = success) |
mcc | string | Mobile Country Code |
mnc | string | Mobile Network Code |
ok | boolean | true if lookup successful |
operator | string | Network operator name |
phone | string | Queried phone number |
ported | integer | 1 if number was ported, 0 if not |
price | float | Cost to send SMS to this number |
regionCode | integer | Region/area code |
timeZone | integer | Timezone offset from UTC |
Code Examples
PHP - Operator Lookup
<?php
function getOperatorInfo($login, $apiKey, $phone) {
// Get timestamp
$timestamp = trim(file_get_contents('https://www.lightsms.com/external/get/timestamp.php'));
// Prepare parameters
$params = [
'login' => $login,
'phone' => $phone,
'timestamp' => $timestamp,
'return' => 'json'
];
// Create signature
ksort($params);
$signature = md5(implode($params) . $apiKey);
$params['signature'] = $signature;
// Make request
$url = 'https://www.lightsms.com/external/get/operator.php?' . http_build_query($params);
$response = file_get_contents($url);
return json_decode($response, true);
}
// Configuration
$login = 'YourLogin';
$apiKey = 'your_api_key_here';
$phone = '37061234567';
// Get operator info
$info = getOperatorInfo($login, $apiKey, $phone);
if ($info['ok']) {
echo "Phone: {$info['phone']}\n";
echo "Operator: {$info['operator']}\n";
echo "Price: {$info['price']} {$info['currency']}\n";
echo "Ported: " . ($info['ported'] ? 'Yes' : 'No') . "\n";
echo "Timezone: UTC{$info['timeZone']:+d}\n";
} else {
echo "Error code: {$info['error']}\n";
}
?>
Python - Validate Numbers Before Sending
import requests
import hashlib
from urllib.parse import urlencode
def get_operator_info(login, api_key, phone):
# Get timestamp
timestamp_response = requests.get('https://www.lightsms.com/external/get/timestamp.php')
timestamp = timestamp_response.text.strip()
# Prepare parameters
params = {
'login': login,
'phone': phone,
'timestamp': timestamp,
'return': 'json'
}
# Create signature
sorted_params = sorted(params.items())
param_string = ''.join([str(value) for key, value in sorted_params])
signature = hashlib.md5((param_string + api_key).encode()).hexdigest()
params['signature'] = signature
# Make request
url = f'https://www.lightsms.com/external/get/operator.php?{urlencode(params)}'
response = requests.get(url)
return response.json()
def validate_and_send(login, api_key, phone, message):
"""Validate phone number before sending SMS."""
# Check operator info
info = get_operator_info(login, api_key, phone)
if not info['ok']:
print(f"❌ Invalid phone number: {phone}")
return False
# Log operator details
print(f"✅ Valid number: {phone}")
print(f" Operator: {info['operator']}")
print(f" Price: {info['price']} {info['currency']}")
if info['ported']:
print(f" ⚠️ Number has been ported")
# Calculate cost estimate
message_parts = len(message) // 160 + 1
estimated_cost = info['price'] * message_parts
print(f" Estimated cost: {estimated_cost:.4f} {info['currency']}")
# Proceed with sending
return True
# Configuration
LOGIN = 'YourLogin'
API_KEY = 'your_api_key_here'
# Validate before sending
phone = '37061234567'
message = 'Hello from LightSMS!'
if validate_and_send(LOGIN, API_KEY, phone, message):
# Send SMS
print("Proceeding with SMS sending...")
JavaScript - Bulk Number Validation
const crypto = require('crypto');
const axios = require('axios');
async function getOperatorInfo(login, apiKey, phone) {
// Get timestamp
const timestampResponse = await axios.get('https://www.lightsms.com/external/get/timestamp.php');
const timestamp = timestampResponse.data.trim();
// Prepare parameters
const params = {
login: login,
phone: phone,
timestamp: timestamp,
return: 'json'
};
// Create signature
const sortedKeys = Object.keys(params).sort();
const paramString = sortedKeys.map(key => params[key]).join('');
const signature = crypto.createHash('md5').update(paramString + apiKey).digest('hex');
params.signature = signature;
// Make request
const queryString = new URLSearchParams(params).toString();
const url = `https://www.lightsms.com/external/get/operator.php?${queryString}`;
const response = await axios.get(url);
return response.data;
}
async function validatePhoneList(login, apiKey, phoneNumbers) {
const results = {
valid: [],
invalid: [],
ported: [],
totalCost: 0
};
for (const phone of phoneNumbers) {
try {
const info = await getOperatorInfo(login, apiKey, phone);
if (info.ok) {
results.valid.push({
phone: phone,
operator: info.operator,
price: info.price
});
if (info.ported) {
results.ported.push(phone);
}
results.totalCost += info.price;
} else {
results.invalid.push(phone);
}
// Rate limiting - wait 100ms between requests
await new Promise(resolve => setTimeout(resolve, 100));
} catch (error) {
console.error(`Error validating ${phone}:`, error.message);
results.invalid.push(phone);
}
}
return results;
}
// Configuration
const LOGIN = 'YourLogin';
const API_KEY = 'your_api_key_here';
// Validate list of numbers
const phoneNumbers = [
'37061234567',
'37062345678',
'37063456789'
];
(async () => {
console.log('Validating phone numbers...\n');
const results = await validatePhoneList(LOGIN, API_KEY, phoneNumbers);
console.log(`✅ Valid numbers: ${results.valid.length}`);
console.log(`❌ Invalid numbers: ${results.invalid.length}`);
console.log(`⚠️ Ported numbers: ${results.ported.length}`);
console.log(`💰 Estimated total cost: ${results.totalCost.toFixed(4)} EUR\n`);
console.log('Valid numbers:');
results.valid.forEach(item => {
console.log(` - ${item.phone} (${item.operator}) - ${item.price} EUR`);
});
if (results.invalid.length > 0) {
console.log('\nInvalid numbers:');
results.invalid.forEach(phone => console.log(` - ${phone}`));
}
})();
HLR Statistics
Get statistics about HLR requests for a specific date range.
Endpoint:
GET https://www.lightsms.com/external/get/hlr_stat.php
Required Parameters:
| Parameter | Type | Description |
|---|---|---|
login | string | Your LightSMS login |
signature | string | MD5 signature |
from | string | Start date (format: YYYY-MM-DD) |
to | string | End date (format: YYYY-MM-DD) |
timestamp | integer | UTC timestamp |
Optional Parameters:
| Parameter | Type | Description |
|---|---|---|
return | string | Response format: json or xml |
HLR Statistics Example
curl "https://www.lightsms.com/external/get/hlr_stat.php?login=YourLogin&from=2025-01-01&to=2025-01-31&signature=generated_signature×tamp=1732809600&return=json"
Use Cases
1. List Cleaning
Remove invalid numbers before sending campaigns:
function cleanPhoneList($login, $apiKey, $phoneList) {
$validNumbers = [];
$invalidNumbers = [];
foreach ($phoneList as $phone) {
$info = getOperatorInfo($login, $apiKey, $phone);
if ($info['ok']) {
$validNumbers[] = $phone;
} else {
$invalidNumbers[] = $phone;
}
// Rate limiting
usleep(100000); // 100ms delay
}
echo "Valid: " . count($validNumbers) . "\n";
echo "Invalid: " . count($invalidNumbers) . "\n";
return $validNumbers;
}
2. Cost Estimation
Calculate campaign costs before sending:
def estimate_campaign_cost(login, api_key, phone_list, message_length):
total_cost = 0
message_parts = (message_length // 160) + 1
for phone in phone_list:
info = get_operator_info(login, api_key, phone)
if info['ok']:
total_cost += info['price'] * message_parts
return total_cost
# Example
phones = ['37061234567', '37062345678', '37063456789']
message_length = 150 # characters
cost = estimate_campaign_cost(LOGIN, API_KEY, phones, message_length)
print(f"Campaign estimated cost: {cost:.2f} EUR")
3. Operator-Based Segmentation
Group recipients by operator for targeted campaigns:
async function segmentByOperator(login, apiKey, phoneList) {
const segments = {};
for (const phone of phoneList) {
const info = await getOperatorInfo(login, apiKey, phone);
if (info.ok) {
const operator = info.operator;
if (!segments[operator]) {
segments[operator] = [];
}
segments[operator].push(phone);
}
await new Promise(resolve => setTimeout(resolve, 100));
}
return segments;
}
// Send different messages to different operators
const segments = await segmentByOperator(LOGIN, API_KEY, phoneList);
for (const [operator, phones] of Object.entries(segments)) {
console.log(`${operator}: ${phones.length} recipients`);
// Send targeted message to this operator's customers
}
Pricing Information
Get pricing for all available network operators.
Endpoint:
GET https://www.lightsms.com/external/get/prices.php
Required Parameters:
| Parameter | Type | Description |
|---|---|---|
login | string | Your LightSMS login |
signature | string | MD5 signature |
timestamp | integer | UTC timestamp |
Pricing Response Example
curl "https://www.lightsms.com/external/get/prices.php?login=YourLogin&signature=generated_signature×tamp=1732809600"
Response (JSON):
{
"24602": {
"NETWORK_NAME": "Tele2 Lithuania",
"COUNTRY": "Lithuania",
"PRICE": "0.012",
"CURRENCY": "EUR"
},
"24601": {
"NETWORK_NAME": "Omnitel (Telia)",
"COUNTRY": "Lithuania",
"PRICE": "0.012",
"CURRENCY": "EUR"
},
"24603": {
"NETWORK_NAME": "Bite Lithuania",
"COUNTRY": "Lithuania",
"PRICE": "0.012",
"CURRENCY": "EUR"
}
}
Common Errors
Error 36: Cannot Obtain Information About Phone
Problem: HLR lookup failed for the phone number
Possible causes:
- Invalid phone number format
- Number doesn't exist
- Network temporarily unavailable
Solutions:
- ✅ Verify phone number format (international format)
- ✅ Retry after a short delay
- ✅ Contact support if persistent
Next Steps
Need Help?
For questions about HLR and operator lookup:
- Email: [email protected]
- Phone: Contact Information
- Hours: Monday-Friday, 8:00-20:00 (EET)