Quay lại tất cả bài viết
Hướng dẫn·2026-08-01·7 phút đọc

Tự động hóa xác minh SMS: hướng dẫn API toàn diện

Mọi thứ từ tạo API key, đặt order đến polling lấy mã — kèm ví dụ curl thực tế, giới hạn tần suất, và những cạm bẫy khiến nhiều người mắc phải.

Trang web đủ dùng cho việc đăng ký thỉnh thoảng: bấm vài lần, chờ một tin nhắn. Nó không còn đủ dùng khi bạn viết automated test, script đăng ký hàng loạt, CI pipeline, hoặc một bot cần tự lấy mã xác minh mà không cần người can thiệp. Trang web không làm được điều đó. API thì làm được. Đây là mọi thứ bạn cần để đi từ con số 0 đến một luồng hoạt động hoàn chỉnh.

Bước 1: lấy API key

Đăng nhập rồi vào /account/api-keys để tạo một key. Key có dạng jm_ theo sau là một chuỗi ngẫu nhiên. Bản đầy đủ chỉ hiển thị đúng một lần — chúng tôi lưu bản hash, không lưu key gốc, nên sẽ không có chuyện "khôi phục lại key" nếu bạn làm mất. Xóa nó và tạo key mới.

Mọi request đều dùng xác thực Bearer chuẩn:

Authorization: Bearer jm_your_key

Hãy coi key như một mật khẩu — không commit nó vào repo public, không dán vào đoạn chat để nhờ người khác debug giúp. Nếu nghi ngờ key bị lộ, quay lại /account/api-keys, xóa nó và tạo key mới; key cũ sẽ ngừng hoạt động ngay lập tức.

Bước 2: chọn service và quốc gia

Tạo order cần hai thứ: service (mã service) và country (id quốc gia). Bắt đầu bằng cách xem danh sách catalog:

curl https://jiema.my/api/v1/services \
  -H "Authorization: Bearer jm_your_key"

Mỗi item có field code (Telegram là tg) — dùng thẳng giá trị đó cho endpoint tạo order, đáng tin cậy hơn là tự dựng slug. Để xem giá và tồn kho theo thời gian thực của một service qua các quốc gia, thêm tham số service:

curl "https://jiema.my/api/v1/prices?service=tg" \
  -H "Authorization: Bearer jm_your_key"

Mỗi mục trong itemscountryId / priceCents / count (số lượng số điện thoại còn khả dụng hiện tại). Kiểm tra count trước khi đặt order — bằng 0 nghĩa là order chắc chắn thất bại, đừng tốn một request chỉ để biết điều đó theo cách tốn kém.

Bước 3: tạo order

curl -X POST https://jiema.my/api/v1/orders \
  -H "Authorization: Bearer jm_your_key" \
  -H "Content-Type: application/json" \
  -d '{"service":"tg","country":"6"}'

Một order thành công trả về số điện thoại và thời điểm hết hạn:

{
  "ok": true,
  "data": {
    "id": "cm...",
    "status": "WAITING",
    "phone": "62812xxxxxxx",
    "expiresAt": "2026-08-01T12:15:00.000Z",
    "chargedCents": "40"
  }
}

Tiền bị trừ ngay ở bước này — chargedCents là số tiền thực tế bị trừ (theo cent). Đưa số điện thoại này cho ứng dụng đích để nhận mã xác minh, rồi chuyển sang bước tiếp theo.

Bước 4: polling để lấy mã

Không có WebSocket hay webhook push — bạn lấy nội dung SMS bằng cách polling GET /api/v1/orders/:id cho đến khi smsBody không còn là null:

while true; do
  RESP=$(curl -s https://jiema.my/api/v1/orders/$ORDER_ID \
    -H "Authorization: Bearer jm_your_key")
  BODY=$(echo "$RESP" | jq -r '.data.smsBody')
  if [ "$BODY" != "null" ]; then
    echo "Code received: $BODY"
    break
  fi
  sleep 5
done

Năm giây là một điểm khởi đầu hợp lý — số điện thoại có hiệu lực trong 15 phút, và giới hạn 60 request/phút cho truy vấn vẫn còn thừa khá nhiều dư địa. Ba giây cũng được nếu bạn sốt ruột; polling mỗi giây không giúp mã đến nhanh hơn, nó chỉ tiêu tốn giới hạn tần suất của bạn.

Những điều cần lưu ý

  • Giới hạn tần suất tính theo user, không theo key. Endpoint ghi (order / cancel / next-sms) giới hạn 10 lần/phút cho mỗi user; endpoint đọc là 60 lần/phút. Tạo thêm key không giúp bạn có hạn mức cao hơn — tất cả key đều dùng chung một hạn mức.
  • Số điện thoại hết hạn sau 15 phút. Một số không dùng đến và hết hạn mà chưa nhận được mã sẽ được hoàn tiền tự động — không cần yêu cầu. Nhưng nếu pipeline của bạn giữ số đó quá lâu trước khi thực sự dùng đến (ví dụ bị kẹt trong queue), nó sẽ hết hạn trước khi đến lượt bạn dùng.
  • Một số điện thoại có thể nhận nhiều hơn một mã. Nếu ứng dụng đích gửi SMS theo hai bước (một mã xác nhận đăng ký, sau đó một mã đăng nhập riêng), gọi POST /api/v1/orders/:id/next-sms sau khi mã đầu tiên đến để báo cho chúng tôi biết "đã xong mã này, tiếp tục lắng nghe" — không cần tạo order mới cho một số mới.
  • Khi mã đã đến, cancel sẽ không còn tác dụng. POST /api/v1/orders/:id/cancel hoàn tiền ngay lập tức trong khi số vẫn đang chờ mã. Khi smsBody đã từng khác null, cùng một lệnh gọi đó sẽ trả về lỗi CODE_RECEIVED — bạn đã nhận được thứ mình trả tiền cho, nên không thể hoàn lại nữa.
  • Đừng chỉ kiểm tra status một lần rồi bỏ cuộc. status chuyển từ WAITING sang RECEIVED. Nếu nó cứ ở WAITING cho đến khi hết hạn, thường là do tỷ lệ gửi SMS thành công của cặp quốc gia/service đó đang thấp — đặt order mới ở một quốc gia khác thường có kết quả nhanh hơn là cố chờ.

Bước tiếp theo

Trên đây là toàn bộ luồng chính từ order đến khi nhận mã. Danh sách field đầy đủ, mã lỗi, và các trường hợp biên của từng endpoint có tại /api-docs. Nếu bạn chạy ở quy mô lớn — ví dụ duy trì luồng xác minh cho hàng chục tài khoản cùng lúc — hãy tính thời gian polling cho từng order một cách độc lập. Đừng xếp hàng tất cả trong một vòng lặp tuần tự, nếu không những số điện thoại đến trước sẽ hết hạn trong khi bạn vẫn còn đang chờ cái đầu tiên.

Kiếm 10% trên mỗi đơn hàng từ bất kỳ ai bạn mời

Không giới hạn, không hết hạn. Chia sẻ liên kết, nhận hoa hồng suốt đời mỗi tài khoản đăng ký qua đó.

Lấy liên kết của tôi