API SMSCode cho phép tự động hóa hoàn toàn quy trình mua số ảo và nhận OTP — không cần thao tác thủ công qua dashboard. Với hơn 1.000 dịch vụ và 200+ quốc gia được hỗ trợ, API phù hợp cho developer xây dựng automation, QA engineer kiểm thử, hoặc doanh nghiệp cần xử lý xác minh số lượng lớn. Rate limit mặc định cho phép 60 đơn hàng/phút — đủ cho phần lớn ứng dụng.
TL;DR: API SMSCode là REST API chuẩn với Bearer Token auth. Ba endpoint cốt lõi:
GET /v1/catalog(tìm số),POST /v1/orders(mua số),GET /v1/orders/{id}(lấy OTP). Tích hợp trong dưới 50 dòng code bất kỳ ngôn ngữ nào. Từ 1.200đ/số, hoàn tiền tự động nếu OTP không đến.
Tại Sao Cần API Số Ảo?
Khi bạn cần xác minh hàng chục hoặc hàng trăm tài khoản, làm thủ công qua dashboard tốn quá nhiều thời gian. API giải quyết vấn đề này với một số use case quan trọng:
Test automation. Hệ thống QA cần xác minh đăng ký, đăng nhập, hoặc OTP flow — API tích hợp trực tiếp vào pipeline Selenium, Playwright, hoặc Puppeteer.
Quản lý nhiều tài khoản. Doanh nghiệp cần tạo và quản lý nhiều tài khoản cho các nền tảng khác nhau — API cho phép làm điều này có hệ thống và theo dõi được.
Sản phẩm phần mềm. Nếu bạn xây dựng công cụ automation hoặc dịch vụ khác cần xác minh số điện thoại, API SMSCode là hạ tầng nền tảng.
Tiết kiệm thời gian. Mỗi lần xác minh thủ công tốn 3–5 phút. API giảm xuống còn vài giây và không cần sự tham gia của con người.
Lấy API Key
Trước khi gọi API, bạn cần lấy API key:
- Đăng ký hoặc đăng nhập SMSCode
- Vào Account → API
- Tạo API key mới
- Copy key và lưu ở nơi an toàn — key chỉ hiển thị một lần
Bảo mật API key:
- Không hardcode key vào code
- Dùng biến môi trường:
export SMSCODE_API_KEY="your_key_here" - Không commit key vào git (thêm vào
.gitignore) - Rotate key định kỳ hoặc khi nghi ngờ bị lộ
Base URL Và Xác Thực
Base URL: https://api.smscode.gg/v1
Xác thực qua Bearer Token trong header HTTP:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Tất cả response trả về JSON với cấu trúc nhất quán:
// Thành công
{ "success": true, "data": { ... } }
// Lỗi
{ "success": false, "error": { "code": "ERROR_CODE", "message": "Mô tả lỗi" } }
Các Endpoint Chính
1. Kiểm Tra Số Dư
Kiểm tra số dư hiện tại trước khi đặt đơn:
GET /v1/balance
Response:
{
"success": true,
"data": {
"balance": 3.45,
"currency": "USD"
}
}
2. Tìm Số Khả Dụng (Catalog)
Truy vấn danh sách số có sẵn theo dịch vụ và quốc gia:
GET /v1/catalog?service=telegram&country=id
Tham số:
service: Tên dịch vụ (ví dụ:telegram,facebook,google,tiktok,zalo)country: Mã quốc gia ISO 2 chữ (ví dụ:id= Indonesia,vn= Việt Nam,us= Mỹ,in= Ấn Độ)
Response:
{
"success": true,
"data": {
"products": [
{
"id": "id_telegram_s1",
"country": "ID",
"service": "telegram",
"price": 0.05,
"available": 234
}
]
}
}
3. Đặt Mua Số (Tạo Đơn Hàng)
Mua số và nhận số điện thoại:
POST /v1/orders
Content-Type: application/json
{ "product_id": "id_telegram_s1" }
Response:
{
"success": true,
"data": {
"order_id": "ord_k9x2m7",
"phone": "+6281234567890",
"status": "pending",
"expires_at": "2026-03-17T10:45:00Z"
}
}
Sau bước này, nhập số +6281234567890 vào dịch vụ đích và yêu cầu gửi OTP.
4. Lấy OTP (Poll Đơn Hàng)
Gọi endpoint này lặp lại mỗi 5 giây để kiểm tra OTP:
GET /v1/orders/ord_k9x2m7
Response khi chờ:
{
"success": true,
"data": {
"order_id": "ord_k9x2m7",
"phone": "+6281234567890",
"status": "pending",
"sms_code": null
}
}
Response khi OTP đến:
{
"success": true,
"data": {
"order_id": "ord_k9x2m7",
"phone": "+6281234567890",
"status": "completed",
"sms_code": "847291",
"received_at": "2026-03-17T10:43:15Z"
}
}
5. Hủy Đơn Hàng
Hủy đơn và nhận hoàn tiền nếu OTP chưa đến:
DELETE /v1/orders/ord_k9x2m7
Response:
{
"success": true,
"data": {
"order_id": "ord_k9x2m7",
"status": "cancelled",
"refunded": 0.05
}
}
Code Mẫu — Python
Đây là implementation đầy đủ bằng Python với error handling:
import os
import time
import requests
API_KEY = os.environ.get("SMSCODE_API_KEY")
BASE_URL = "https://api.smscode.gg/v1"
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
def check_balance():
"""Kiểm tra số dư tài khoản."""
r = requests.get(f"{BASE_URL}/balance", headers=HEADERS)
r.raise_for_status()
return r.json()["data"]["balance"]
def find_product(service: str, country: str):
"""Tìm product ID phù hợp."""
r = requests.get(
f"{BASE_URL}/catalog",
params={"service": service, "country": country},
headers=HEADERS
)
r.raise_for_status()
products = r.json()["data"]["products"]
if not products:
raise ValueError(f"Không có số {service} từ {country}")
# Trả về product rẻ nhất có số khả dụng
return min(products, key=lambda p: p["price"])
def buy_number(product_id: str):
"""Mua số và lấy số điện thoại."""
r = requests.post(
f"{BASE_URL}/orders",
json={"product_id": product_id},
headers=HEADERS
)
r.raise_for_status()
return r.json()["data"]
def wait_for_otp(order_id: str, timeout: int = 120) -> str | None:
"""Poll cho đến khi nhận được OTP hoặc hết timeout."""
start = time.time()
while time.time() - start < timeout:
r = requests.get(
f"{BASE_URL}/orders/{order_id}",
headers=HEADERS
)
r.raise_for_status()
data = r.json()["data"]
if data["status"] == "completed":
return data["sms_code"]
elif data["status"] in ("expired", "cancelled"):
return None
time.sleep(5) # Poll mỗi 5 giây
return None # Timeout
def cancel_order(order_id: str):
"""Hủy đơn và nhận hoàn tiền."""
r = requests.delete(
f"{BASE_URL}/orders/{order_id}",
headers=HEADERS
)
r.raise_for_status()
return r.json()["data"]
# Ví dụ sử dụng đầy đủ
def verify_with_telegram():
# 1. Tìm số
product = find_product("telegram", "id")
print(f"Tìm thấy số Indonesia cho Telegram: ${product['price']:.3f}")
# 2. Mua số
order = buy_number(product["id"])
print(f"Số điện thoại: {order['phone']}")
print(f"Order ID: {order['order_id']}")
# 3. TODO: Nhập order['phone'] vào Telegram để yêu cầu OTP
# 4. Chờ OTP
print("Đang chờ OTP...")
otp = wait_for_otp(order["order_id"])
if otp:
print(f"OTP nhận được: {otp}")
# 5. TODO: Nhập OTP vào Telegram
else:
print("Không nhận được OTP — hủy đơn")
cancel_order(order["order_id"])
return otp
if __name__ == "__main__":
balance = check_balance()
print(f"Số dư: ${balance:.2f}")
verify_with_telegram()
Code Mẫu — JavaScript (Node.js)
const API_KEY = process.env.SMSCODE_API_KEY;
const BASE_URL = 'https://api.smscode.gg/v1';
const headers = {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
};
async function apiCall(method, path, body = null) {
const opts = { method, headers };
if (body) opts.body = JSON.stringify(body);
const res = await fetch(`${BASE_URL}${path}`, opts);
const data = await res.json();
if (!data.success) throw new Error(data.error.message);
return data.data;
}
async function findProduct(service, country) {
const { products } = await apiCall('GET', `/catalog?service=${service}&country=${country}`);
if (!products.length) throw new Error(`Không có số ${service} từ ${country}`);
return products.sort((a, b) => a.price - b.price)[0];
}
async function buyNumber(productId) {
return apiCall('POST', '/orders', { product_id: productId });
}
async function waitForOtp(orderId, timeoutMs = 120000) {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
const data = await apiCall('GET', `/orders/${orderId}`);
if (data.status === 'completed') return data.sms_code;
if (['expired', 'cancelled'].includes(data.status)) return null;
await new Promise(r => setTimeout(r, 5000)); // Đợi 5 giây
}
return null;
}
async function cancelOrder(orderId) {
return apiCall('DELETE', `/orders/${orderId}`);
}
// Sử dụng
(async () => {
try {
const product = await findProduct('tiktok', 'in'); // TikTok, Ấn Độ
console.log(`Giá: $${product.price.toFixed(3)}`);
const order = await buyNumber(product.id);
console.log(`Số điện thoại: ${order.phone}`);
// Nhập order.phone vào TikTok tại đây...
const otp = await waitForOtp(order.order_id);
if (otp) {
console.log(`OTP: ${otp}`);
} else {
await cancelOrder(order.order_id);
console.log('Hủy đơn, tiền hoàn lại.');
}
} catch (err) {
console.error('Lỗi:', err.message);
}
})();
Code Mẫu — cURL
Dùng để test nhanh từ terminal:
# Kiểm tra số dư
curl -H "Authorization: Bearer $SMSCODE_API_KEY" \
https://api.smscode.gg/v1/balance
# Tìm số Telegram từ Indonesia
curl -H "Authorization: Bearer $SMSCODE_API_KEY" \
"https://api.smscode.gg/v1/catalog?service=telegram&country=id"
# Mua số
curl -X POST \
-H "Authorization: Bearer $SMSCODE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"product_id": "id_telegram_s1"}' \
https://api.smscode.gg/v1/orders
# Lấy OTP (thay ORDER_ID bằng ID thực)
curl -H "Authorization: Bearer $SMSCODE_API_KEY" \
https://api.smscode.gg/v1/orders/ORDER_ID
# Hủy đơn
curl -X DELETE \
-H "Authorization: Bearer $SMSCODE_API_KEY" \
https://api.smscode.gg/v1/orders/ORDER_ID
Xử Lý Lỗi
Các mã lỗi phổ biến và cách xử lý:
| Mã lỗi | Ý nghĩa | Cách xử lý |
|---|---|---|
INSUFFICIENT_BALANCE | Số dư không đủ | Nạp thêm tiền |
PRODUCT_NOT_FOUND | Product ID không tồn tại | Kiểm tra lại catalog |
NO_NUMBERS_AVAILABLE | Hết số từ quốc gia đó | Thử quốc gia khác |
ORDER_NOT_FOUND | Order ID không tồn tại | Kiểm tra lại order ID |
ORDER_EXPIRED | Đơn đã hết hạn | Mua số mới và thử lại |
ORDER_ALREADY_COMPLETED | Đơn đã hoàn thành | OTP đã đến, không cần hủy |
RATE_LIMITED | Quá nhiều request | Giảm tần suất, thêm delay |
UNAUTHORIZED | API key sai hoặc hết hạn | Kiểm tra và rotate API key |
Retry Logic Thông Minh
import time
def buy_with_retry(service, country, max_attempts=3):
"""Thử mua số với retry khi thất bại."""
for attempt in range(max_attempts):
try:
product = find_product(service, country)
return buy_number(product["id"])
except Exception as e:
error_msg = str(e)
if "NO_NUMBERS_AVAILABLE" in error_msg:
# Thử quốc gia khác
countries = ["id", "in", "br", "us"]
country = countries[(countries.index(country) + 1) % len(countries)]
print(f"Không có số {country}, thử {countries[attempt+1 if attempt+1 < len(countries) else 0]}")
elif "INSUFFICIENT_BALANCE" in error_msg:
raise # Không retry khi hết tiền
else:
time.sleep(2 ** attempt) # Exponential backoff
raise Exception(f"Không thể mua số sau {max_attempts} lần thử")
Best Practices Và Rate Limits
Rate Limits
Rate limits mặc định của SMSCode API:
- Tạo đơn hàng: 60 đơn/phút
- Kiểm tra đơn hàng (poll): 300 request/phút
- Catalog: 120 request/phút
- Balance: 60 request/phút
Với volume cao hơn, liên hệ hỗ trợ để tăng limits.
Polling Thông Minh
Đừng poll liên tục mỗi giây — đây là cách lãng phí request và có thể bị rate limit:
# Không nên — quá dày
while True:
otp = check_otp(order_id)
if otp: break
time.sleep(1) # 1 giây là quá nhanh
# Nên — đủ dùng và không lãng phí
while True:
otp = check_otp(order_id)
if otp: break
time.sleep(5) # 5 giây là hợp lý
Timeout Hợp Lý
Đặt timeout 90–120 giây cho mỗi đơn hàng. Nếu quá timeout, hủy đơn và mua số mới. Tiền hoàn tự động.
Xử Lý Song Song
Nếu cần xử lý nhiều số đồng thời, dùng asyncio (Python) hoặc Promise.all (JavaScript):
// Xử lý 5 đơn hàng song song
const orders = await Promise.all([
buyNumber(productId),
buyNumber(productId),
buyNumber(productId),
buyNumber(productId),
buyNumber(productId)
]);
Tích Hợp Với Test Automation
Đây là use case phổ biến nhất với developers:
Playwright (Python)
from playwright.sync_api import sync_playwright
import time
def test_telegram_signup():
product = find_product("telegram", "id")
order = buy_number(product["id"])
phone = order["phone"]
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
# Điều hướng đến Telegram Web
page.goto("https://web.telegram.org/")
# Nhập số điện thoại
page.fill('[type="tel"]', phone)
page.click('button[type="submit"]')
# Chờ OTP
time.sleep(5)
otp = wait_for_otp(order["order_id"])
assert otp is not None, "OTP không đến"
# Nhập OTP
page.fill('.input-field-input', otp)
# Xác nhận thành công
page.wait_for_selector('.chat-list')
print("Telegram đăng nhập thành công!")
browser.close()
FAQ
API có hỗ trợ webhook không?
Hiện tại dùng polling model — gọi GET /v1/orders/{id} mỗi 5 giây để kiểm tra. Webhook đang trong roadmap phát triển.
Có thể dùng API từ browser (JavaScript phía client) không?
Không khuyến nghị — vì sẽ lộ API key cho người dùng. Chỉ nên gọi API từ phía server (Node.js backend, Python script, v.v.).
Làm thế nào để test mà không tốn nhiều tiền?
Dùng quốc gia có giá thấp nhất (Indonesia, Ấn Độ, Nga) cho môi trường dev. Khi production ready, chuyển sang quốc gia tốt nhất cho dịch vụ cụ thể.
API có tài liệu Swagger/OpenAPI không?
Có — truy cập https://api.smscode.gg/docs sau khi đăng nhập. Tài liệu cập nhật đầy đủ với tất cả endpoint, tham số, và ví dụ response.
Tôi cần xử lý hàng trăm số mỗi giờ — API có đủ không?
Với 60 đơn/phút mặc định, bạn có thể xử lý đến 3.600 đơn/giờ. Nếu cần nhiều hơn, liên hệ hỗ trợ để thảo luận về rate limit cao hơn.
API SMSCode cho phép bạn tích hợp số ảo vào bất kỳ workflow nào — từ test automation đến production service. Đăng ký SMSCode và lấy API key miễn phí. Đọc thêm nhận SMS online — hướng dẫn đầy đủ để hiểu thêm về quy trình nhận OTP, hoặc số ảo cho kinh doanh để khám phá use case thực tế.