Tài liệu API
Truy cập lập trình đến số ảo, đơn hàng và số dư tài khoản.
⟩ Xác thực
Tất cả yêu cầu API đều yêu cầu Bearer token. Tạo token từ Cài đặt tài khoản trong bảng điều khiển, sau đó đính kèm vào mỗi yêu cầu:
Yêu cầu không có token hợp lệ sẽ nhận phản hồi 401 UNAUTHORIZED.
⟩ URL cơ sở
Tất cả đường dẫn endpoint bên dưới tương đối với:
⟩ Định dạng phản hồi
Mọi phản hồi trả về JSON với cấu trúc nhất quán. Tất cả phản hồi bao gồm header x-request-id để gỡ lỗi.
{
"success": true,
"data": { ... }
} {
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable message"
}
} /catalog/countries Trả về danh sách tất cả quốc gia có sẵn.
Tham số
Không có
Ví dụ yêu cầu
curl -s https://api.smscode.gg/v1/catalog/countries \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/catalog/countries", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/catalog/countries",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": [
{
"id": 6,
"code": "ID",
"name": "Indonesia",
"dial_code": "+62",
"emoji": "🇮🇩",
"active": true
}
]
} /catalog/services Trả về danh sách dịch vụ (nền tảng) có sẵn. Có thể lọc theo quốc gia.
Tham số truy vấn
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
country_id | integer | Không | Lọc dịch vụ có sẵn cho quốc gia này |
Ví dụ yêu cầu
curl -s "https://api.smscode.gg/v1/catalog/services?country_id=6" \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/catalog/services?country_id=6", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/catalog/services",
params={"country_id": 6},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": [
{
"id": 3,
"code": "wa",
"name": "WhatsApp",
"active": true
}
]
} /catalog/products Trả về danh sách sản phẩm có sẵn (phân trang). Lọc theo quốc gia và/hoặc nền tảng.
Tham số truy vấn
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
country_id | integer | Không | Lọc theo ID quốc gia |
platform_id | integer | Không | Lọc theo ID nền tảng/dịch vụ |
sort | string | Không | Thứ tự sắp xếp: price_asc (mặc định), price_desc, available_asc, available_desc, name_asc, name_desc |
limit | integer | Không | Số kết quả mỗi trang (1-10.000, mặc định 1.000) |
page | integer | Không | Số trang (tối thiểu 1, mặc định 1) |
Ví dụ yêu cầu
curl -s "https://api.smscode.gg/v1/catalog/products?country_id=6&platform_id=3&limit=10&page=1" \
-H "Authorization: Bearer YOUR_API_TOKEN" const params = new URLSearchParams({
country_id: "6", platform_id: "3", limit: "10", page: "1",
});
const res = await fetch(`https://api.smscode.gg/v1/catalog/products?${params}`, {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/catalog/products",
params={"country_id": 6, "platform_id": 3, "limit": 10, "page": 1},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": [
{
"id": 142,
"name": "WhatsApp Indonesia",
"country_id": 6,
"platform_id": 3,
"available": 42,
"price": 15000,
"active": true
}
],
"meta": { "page": 1, "limit": 10, "count": 1 }
} /catalog/exchange-rate Trả về tỷ giá hối đoái hiện tại cho một cặp tiền tệ. Hữu ích để chuyển đổi giá.
Tham số truy vấn
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
pair | string | Không | Cặp tiền tệ (mặc định: USD/IDR) |
Ví dụ yêu cầu
curl -s "https://api.smscode.gg/v1/catalog/exchange-rate?pair=USD/IDR" \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/catalog/exchange-rate?pair=USD/IDR", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/catalog/exchange-rate",
params={"pair": "USD/IDR"},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": {
"pair": "USD/IDR",
"base_currency": "USD",
"quote_currency": "IDR",
"rate": 16250
}
} /balance Trả về số dư tài khoản của người dùng đã xác thực bằng IDR.
Tham số
Không có
Ví dụ yêu cầu
curl -s https://api.smscode.gg/v1/balance \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/balance", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/balance",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": {
"currency": "IDR",
"balance": 500000
}
} /orders Trả về danh sách đơn hàng của người dùng đã xác thực, sắp xếp theo mới nhất. Hỗ trợ lọc theo trạng thái và phân trang qua offset.
Tham số truy vấn
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
limit | integer | Không | Số kết quả tối đa (1-100, mặc định 20) |
offset | integer | Không | Số kết quả bỏ qua (mặc định 0) |
status | string | Không | Lọc theo trạng thái: ACTIVE, OTP_RECEIVED, COMPLETED, CANCELED, EXPIRED (không phân biệt hoa thường) |
Ví dụ yêu cầu
curl -s "https://api.smscode.gg/v1/orders?limit=5&status=ACTIVE" \
-H "Authorization: Bearer YOUR_API_TOKEN" const params = new URLSearchParams({
limit: "5", status: "ACTIVE", offset: "0",
});
const res = await fetch(`https://api.smscode.gg/v1/orders?${params}`, {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/orders",
params={"limit": 5, "status": "ACTIVE", "offset": 0},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": [
{
"id": 1001,
"status": "ACTIVE",
"created_at": "2026-02-25T10:00:00Z",
"product_id": 142,
"phone_number": "+6281234567890",
"amount": 15000,
"otp_code": null,
"otp_received_at": null,
"expires_at": "2026-02-25T10:20:00Z",
"canceled_at": null,
"failed_reason": null
}
]
} /orders/{id} Trả về một đơn hàng theo ID. Chỉ trả về đơn hàng của người dùng đã xác thực.
Tham số đường dẫn
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
id | integer | Có | Mã đơn hàng (tham số đường dẫn) |
Ví dụ yêu cầu
curl -s https://api.smscode.gg/v1/orders/1001 \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/orders/1001", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/orders/1001",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": {
"id": 1001,
"status": "OTP_RECEIVED",
"created_at": "2026-02-25T10:00:00Z",
"product_id": 142,
"phone_number": "+6281234567890",
"amount": 15000,
"otp_code": "123456",
"otp_received_at": "2026-02-25T10:05:00Z",
"expires_at": "2026-02-25T10:20:00Z",
"canceled_at": null,
"failed_reason": null
}
} /orders/active Liệt kê tất cả đơn hàng đang hoạt động (ACTIVE + OTP_RECEIVED). Sử dụng để theo dõi cập nhật trạng thái OTP.
Tham số
Không có
Ví dụ yêu cầu
curl -s https://api.smscode.gg/v1/orders/active \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/orders/active", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/orders/active",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": [
{
"id": 1001,
"status": "OTP_RECEIVED",
"otp_code": "123456",
"otp_message": "Your verification code is 123456",
"otp_received_at": "2026-02-25T10:05:00Z",
"expires_at": "2026-02-25T10:20:00Z",
"failed_reason": null
},
{
"id": 1002,
"status": "ACTIVE",
"otp_code": null,
"otp_message": null,
"otp_received_at": null,
"expires_at": "2026-02-25T10:50:00Z",
"failed_reason": null
}
]
} /orders/create Tạo đơn hàng số ảo mới. Tự động trừ số dư. Hỗ trợ header Idempotency-Key tùy chọn để tránh tạo đơn trùng lặp khi thử lại do lỗi mạng.
Nội dung yêu cầu
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
product_id | integer | Có | ID sản phẩm cần đặt hàng |
quantity | integer | Không | Số lượng (1-100, mặc định 1) |
Truyền header Idempotency-Key (chuỗi bất kỳ duy nhất) để thử lại yêu cầu an toàn mà không tạo đơn trùng lặp.
Ví dụ yêu cầu
curl -s -X POST https://api.smscode.gg/v1/orders/create \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-request-id-123" \
-d '{"product_id":142,"quantity":1}' const res = await fetch("https://api.smscode.gg/v1/orders/create", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json",
"Idempotency-Key": "unique-request-id-123",
},
body: JSON.stringify({ product_id: 142, quantity: 1 }),
});
const data = await res.json(); import requests
res = requests.post("https://api.smscode.gg/v1/orders/create",
json={"product_id": 142, "quantity": 1},
headers={
"Authorization": "Bearer YOUR_API_TOKEN",
"Idempotency-Key": "unique-request-id-123",
})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": {
"orders": [
{
"id": 1002,
"status": "ACTIVE",
"phone_number": "+6281234567891",
"otp_code": null,
"otp_received_at": null,
"expires_at": "2026-02-25T10:50:00Z",
"failed_reason": null
}
],
"failed_count": 0
}
} /orders/cancel Hủy đơn hàng đang hoạt động. Phí thuê sẽ được hoàn vào số dư tài khoản.
Nội dung yêu cầu
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
id | integer | Có | Mã đơn hàng cần hủy |
Ví dụ yêu cầu
curl -s -X POST https://api.smscode.gg/v1/orders/cancel \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":1001}' const res = await fetch("https://api.smscode.gg/v1/orders/cancel", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ id: 1001 }),
});
const data = await res.json(); import requests
res = requests.post("https://api.smscode.gg/v1/orders/cancel",
json={"id": 1001},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": {
"order_id": 1001,
"status": "CANCELED",
"refund_amount": 15000,
"new_balance": 515000
}
} /orders/finish Đánh dấu đơn hàng đã hoàn thành sau khi nhận OTP. Giải phóng số ngay lập tức thay vì đợi hết hạn.
Nội dung yêu cầu
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
id | integer | Có | Mã đơn hàng cần hoàn thành |
Ví dụ yêu cầu
curl -s -X POST https://api.smscode.gg/v1/orders/finish \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":1001}' const res = await fetch("https://api.smscode.gg/v1/orders/finish", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ id: 1001 }),
});
const data = await res.json(); import requests
res = requests.post("https://api.smscode.gg/v1/orders/finish",
json={"id": 1001},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": {
"order_id": 1001,
"status": "COMPLETED"
}
} /orders/resend Yêu cầu nền tảng gửi lại SMS đến số đã thuê. Không phải tất cả nền tảng đều hỗ trợ gửi lại — kiểm tra trường resent trong phản hồi.
Nội dung yêu cầu
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
id | integer | Có | Mã đơn hàng cần gửi lại SMS |
Ví dụ yêu cầu
curl -s -X POST https://api.smscode.gg/v1/orders/resend \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":1001}' const res = await fetch("https://api.smscode.gg/v1/orders/resend", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ id: 1001 }),
});
const data = await res.json(); import requests
res = requests.post("https://api.smscode.gg/v1/orders/resend",
json={"id": 1001},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": {
"order_id": 1001,
"status": "ACTIVE",
"resent": true
}
} /webhook Trả về cấu hình webhook notification hiện tại của bạn.
Tham số
Không có
Ví dụ yêu cầu
curl -s https://api.smscode.gg/v1/webhook \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/webhook", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/webhook",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": {
"webhook_url": "https://example.com/webhook",
"webhook_secret": "a1b2c3d4e5f6..."
}
} /webhook Cập nhật URL webhook và/hoặc secret. Secret được tự động tạo khi bạn đặt URL lần đầu. Gửi chuỗi rỗng để xóa. URL phải sử dụng HTTPS.
Nội dung yêu cầu
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
webhook_url | string | Không | URL HTTPS để nhận sự kiện webhook (chuỗi rỗng để xóa) |
webhook_secret | string | Không | Secret chia sẻ cho chữ ký HMAC-SHA256 (tự động tạo nếu bỏ qua lần đặt đầu tiên) |
Cần ít nhất một trường.
Ví dụ yêu cầu
curl -s -X PATCH https://api.smscode.gg/v1/webhook \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"webhook_url":"https://example.com/webhook"}' const res = await fetch("https://api.smscode.gg/v1/webhook", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ webhook_url: "https://example.com/webhook" }),
});
const data = await res.json(); import requests
res = requests.patch("https://api.smscode.gg/v1/webhook",
json={"webhook_url": "https://example.com/webhook"},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": {
"webhook_url": "https://example.com/webhook",
"webhook_secret": "a1b2c3d4e5f6..."
}
} /webhook/test Gửi sự kiện thử nghiệm đến URL webhook đã cấu hình. Trả về mã trạng thái HTTP từ máy chủ của bạn. Hữu ích để kiểm tra endpoint hoạt động trước khi vận hành chính thức.
Tham số
Không có
Ví dụ yêu cầu
curl -s -X POST https://api.smscode.gg/v1/webhook/test \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/webhook/test", {
method: "POST",
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.post("https://api.smscode.gg/v1/webhook/test",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Ví dụ phản hồi
{
"success": true,
"data": {
"status_code": 200
}
} ⟩ Webhook Notifications
Cấu hình URL webhook để nhận thông báo đẩy theo thời gian thực cho các sự kiện đơn hàng thay vì polling. Đây là phương pháp được khuyến nghị cho bot script.
Sự kiện
| Sự kiện | Kích hoạt |
|---|---|
order.otp_received | Mã OTP đã được gửi đến số thuê |
order.completed | Đơn hàng đã hoàn thành (thủ công hoặc khi hết hạn) |
order.expired | Đơn hàng hết hạn mà không có OTP (đã hoàn tiền) |
order.canceled | Đơn hàng bị hủy bởi người dùng (đã hoàn tiền) |
Payload
{
"event": "order.otp_received",
"timestamp": "2026-02-25T12:00:00Z",
"data": {
"order_id": 1001,
"phone_number": "+628123456789",
"otp_code": "1234",
"otp_message": "Your verification code is 1234",
"product_id": 42,
"country": "Indonesia",
"platform": "WhatsApp"
}
} Xác minh chữ ký
Mỗi yêu cầu webhook bao gồm header X-Webhook-Signature chứa chữ ký HMAC-SHA256 của nội dung yêu cầu, sử dụng webhook_secret làm khóa:
Xác minh chữ ký này trên máy chủ để đảm bảo yêu cầu là xác thực. Gửi theo kiểu fire-and-forget với timeout 3 giây và không thử lại.
⟩ Rate Limits
Yêu cầu API được giới hạn tốc độ theo nhóm endpoint. Vượt quá giới hạn trả về 429 Too Many Requests với header Retry-After cho biết số giây cần đợi.
| Nhóm endpoint | Giới hạn | Cửa sổ |
|---|---|---|
| Danh mục (quốc gia, dịch vụ, sản phẩm, tỷ giá) | 1.200 yêu cầu | 60 giây |
| Số dư | 600 yêu cầu | 60 giây |
| Đọc đơn hàng (danh sách, chi tiết, hoạt động) | 1.200 yêu cầu | 60 giây |
| Tạo đơn hàng | 1.200 yêu cầu | 60 giây |
| Hủy đơn hàng | 600 yêu cầu | 60 giây |
| Thao tác đơn hàng (hoàn thành, gửi lại) | 600 yêu cầu | 60 giây |
| Cấu hình webhook (xem, cập nhật, thử) | 120 yêu cầu | 60 giây |
⟩ Mã lỗi
Phản hồi lỗi bao gồm một trong các mã sau trong error.code:
| Mã | HTTP | Mô tả |
|---|---|---|
UNAUTHORIZED | 401 | Thiếu hoặc API token không hợp lệ |
FORBIDDEN | 403 | Truy cập bị từ chối |
NOT_FOUND | 404 | Không tìm thấy tài nguyên (đơn hàng, tỷ giá, v.v.) |
CONFLICT | 409 | Yêu cầu trùng lặp hoặc xung đột tài nguyên |
INSUFFICIENT_BALANCE | 409 | Số dư không đủ để tạo đơn hàng |
VALIDATION_ERROR | 422 | Tham số yêu cầu không hợp lệ |
RATE_LIMIT_EXCEEDED | 429 | Quá nhiều yêu cầu (kiểm tra header Retry-After) |
INTERNAL_ERROR | 500 | Lỗi máy chủ nội bộ |
PROVIDER_ERROR | 422 | Nhà cung cấp SMS thượng nguồn từ chối yêu cầu |
CANCEL_TOO_EARLY | 409 | Đơn hàng quá mới để hủy — hãy đợi 2 phút |
SERVICE_UNAVAILABLE | 503 | Dịch vụ tạm thời không khả dụng (bảo trì) |