Tài liệu API
REST API cho truy cập batch / tự động vào jiema.my. Dùng để tích hợp xác minh SMS vào dịch vụ của bạn. Tất cả endpoint trả về JSON.
Xác thực
Mọi yêu cầu phải chứa API key của bạn:
Authorization: Bearer jm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Dạng header thay thế: X-API-Key: jm_xxx…
Tạo và thu hồi key tại /account/api-keys. Mỗi người dùng có thể giữ tối đa 10 key đang hoạt động. Token đầy đủ chỉ hiển thị một lần khi tạo — hãy lưu giữ an toàn.
Lỗi & giới hạn tần suất
Tất cả lỗi đều trả về JSON:
{ "ok": false, "code": "RATE_LIMITED", "message": "..." }| HTTP | code | ý nghĩa |
|---|---|---|
| 401 | AUTH_MISSING / AUTH_INVALID | Không có key hoặc đã thu hồi |
| 403 | FORBIDDEN | Bị cấm hoặc không có quyền truy cập |
| 400 | BAD_REQUEST / INSUFFICIENT / NO_NUMBERS / … | Lỗi xác thực hoặc lỗi nghiệp vụ |
| 404 | NOT_FOUND | Order không tồn tại (hoặc không phải của bạn) |
| 429 | RATE_LIMITED | Giới hạn theo key |
| 500 | INTERNAL | Lỗi máy chủ (đã tự động báo cáo) |
Giới hạn tần suất: Theo key, cửa sổ trượt 60s. Endpoint ghi (orders, cancel, next-sms) 10 req/min; endpoint đọc (account, services, prices, list) 60 req/min.
GET /v1/account
Lấy số dư hiện tại và thông tin hồ sơ cơ bản.
curl https://jiema.my/api/v1/account \
-H "Authorization: Bearer jm_xxx"
# 200 OK
{ "ok": true, "data": {
"id": "clxxxxxxxxxxx",
"balanceCents": "1200", // string to preserve precision; $12.00
"referralCode": "abc123",
"displayName": "Alice",
"lang": "en"
}}GET /v1/services
Liệt kê các service kèm tồn kho. Cache phía server khoảng 5 phút.
curl https://jiema.my/api/v1/services -H "Authorization: Bearer jm_xxx"
{ "ok": true, "data": { "items": [
{ "code": "tg", "slug": "telegram", "name": "Telegram",
"minCostUsd": 0.18, "totalCount": 1234, "countryCount": 24 },
...
] }}Dùng code (hoặc slug thân thiện) làm trường service khi tạo order.
GET /v1/countries
curl https://jiema.my/api/v1/countries -H "Authorization: Bearer jm_xxx"
{ "ok": true, "data": { "items": [
{ "id": 7, "slug": "my", "name": "Malaysia" },
...
] }}id là country id số của upstream; slug là mã ngắn SEO (ví dụ "my" / "us"). Cả hai dạng đều dùng được làm trường country.
GET /v1/prices?service=tg
Giá theo từng quốc gia và tồn kho cho một service nhất định. Giá đã bao gồm markup/giảm giá do bộ phận vận hành cấu hình.
curl "https://jiema.my/api/v1/prices?service=tg" -H "Authorization: Bearer jm_xxx"
{ "ok": true, "data": {
"service": "tg",
"items": [
{ "countryId": 7, "countrySlug": "my", "priceCents": "32", "count": 540 },
...
]
}}POST /v1/orders
Tạo một order xác minh SMS. Hệ thống sẽ giữ một số điện thoại từ upstream và trừ số tiền tương ứng từ số dư của bạn.
curl -X POST https://jiema.my/api/v1/orders \
-H "Authorization: Bearer jm_xxx" \
-H "content-type: application/json" \
-d '{ "service": "tg", "country": 7 }'
{ "ok": true, "data": {
"id": "ckxxxxx",
"status": "WAITING",
"service": "tg",
"country": "7",
"phone": "+60123456789",
"expiresAt": "2026-05-22T08:30:00.000Z",
"chargedCents": "32"
}}Không có trường tùy chọn nào ngoài service / country.
Mã lỗi thường gặp: INSUFFICIENT (cần nạp thêm), NO_NUMBERS, BAD_SERVICE, BAD_COUNTRY.
GET /v1/orders/:id
Polling cho đến khi status trở thành RECEIVED và smsBody không null.
curl https://jiema.my/api/v1/orders/ckxxxxx -H "Authorization: Bearer jm_xxx"
{ "ok": true, "data": {
"id": "ckxxxxx",
"status": "RECEIVED",
"phone": "+60123456789",
"smsBody": "Your verification code is 123456",
"smsHistory": [
{ "body": "Your verification code is 123456", "receivedAt": "..." }
],
"smsReceivedAt": "2026-05-22T08:12:34.000Z",
...
}}Trạng thái: WAITING (số đang hoạt động, chờ SMS) · RECEIVED (đã nhận mã) · COMPLETED / FAILED / CANCELLED là trạng thái cuối.
Polling khuyến nghị: mỗi 3–5 giây. Đồng bộ upstream chạy bên trong endpoint này nên polling sẽ thúc đẩy trạng thái ngay cả khi worker nền đang bận.
POST /v1/orders/:id/cancel
Hủy một order chưa nhận được mã. Hoàn lại toàn bộ vào số dư của bạn.
curl -X POST https://jiema.my/api/v1/orders/ckxxxxx/cancel \
-H "Authorization: Bearer jm_xxx"
{ "ok": true, "data": { "id": "ckxxxxx", "status": "CANCELLED" }}Bị từ chối với CODE_RECEIVED nếu số đã nhận bất kỳ SMS nào, hoặc ALREADY_CHANGED nếu trạng thái thay đổi đồng thời.
POST /v1/orders/:id/next-sms
Sau khi RECEIVED, yêu cầu upstream giữ số tiếp tục hoạt động và chờ một SMS khác (không tính phí thêm trong cửa sổ đang hoạt động).
curl -X POST https://jiema.my/api/v1/orders/ckxxxxx/next-sms \
-H "Authorization: Bearer jm_xxx"
{ "ok": true, "data": { "id": "ckxxxxx", "status": "WAITING" }}GET /v1/orders
Danh sách order gần đây của bạn phân trang theo cursor.
curl "https://jiema.my/api/v1/orders?limit=20" -H "Authorization: Bearer jm_xxx"
{ "ok": true, "data": {
"items": [ { "id": "ck...", "status": "RECEIVED", "service": "tg", ... }, ... ],
"nextCursor": "ck..." | null
}}Tham số truy vấn tùy chọn: status · limit 1–100 (mặc định 20) · cursor = nextCursor của trang trước.
Luồng làm việc điển hình
- Nạp tiền qua UI web → GET /v1/account để xác nhận số dư.
- Chọn service: GET /v1/services và GET /v1/prices?service=tg.
- Tạo order: POST /v1/orders với service + country.
- Đọc data.phone và kích hoạt SMS upstream từ client của bạn (ví dụ dán vào đăng ký Telegram).
- Polling GET /v1/orders/:id mỗi 3–5 giây. Khi status === "RECEIVED", đọc smsBody.
- Nếu SMS sai hoặc muốn nhận mã thứ hai: POST /v1/orders/:id/next-sms → quay lại WAITING.
- Xong. Nếu bạn hủy trước khi có bất kỳ SMS nào: POST /v1/orders/:id/cancel để hoàn tiền toàn bộ.