Tài liệu API

Public API /v1 — xác thực bằng API key, tích hợp tự động vào phần mềm của bạn

API Key của bạn
Bạn chưa đăng nhập — đăng nhập để nhận API key riêng.
Dùng key này trong header Authorization: Bearer <key> hoặc query ?api_key=<key>. Bấm nút mắt để xem key đầy đủ; bấm Tạo key mới khi cần thay thế (key cũ vô hiệu ngay lập tức).

Tổng quan

Base URL
https://otpgmail.net
Xác thực
Thêm API key vào mọi request qua header Authorization: Bearer og_xxx... (khuyến nghị) hoặc query string ?api_key=og_xxx....
Idempotency-Key (chống đơn trùng)
Mọi request POST /v1/orders nên gửi kèm header Idempotency-Key: <UUID mới mỗi đơn>. Nếu request timeout hoặc mất mạng, gửi lại với cùng key cũ — server trả lại đúng response gốc thay vì tạo thêm đơn mới. Sinh UUID mới cho mỗi đơn mới, dùng lại UUID cũ chỉ khi retry.
Loại mail: Gmail hoặc iCloud
Mặc định hệ thống cấp mail @gmail.com. Muốn thuê mail @icloud.com, thêm trường "domain": "icloud.com" vào body POST /v1/orders. Không gửi domain = gmail.comhệ thống cũ của bạn không cần sửa gì. Chỉ dịch vụ có icloud khác null trong GET /v1/services mới thuê được iCloud; giá iCloud có thể khác giá Gmail (xem icloud.price). Mọi response đơn đều có trường domain cho biết đơn thuộc loại mail nào.

Endpoints

GET/v1/balance
Trả về số dư tài khoản (đơn vị: đồng VND) tương ứng với API key được dùng.
Ví dụ
curl "https://otpgmail.net/v1/balance" \
  -H "Authorization: Bearer og_xxx..."
Response mẫu
{
  "success": true,
  "data": {
    "balance": 25000
  }
}
Lỗi có thể gặp: UNAUTHORIZED
GET/v1/services
Danh sách dịch vụ đang bật — code, tên, giá thuê Gmail (đồng VND), tồn kho Gmail hiện tại, và khối icloud: giá + tồn kho khi thuê mail @icloud.com. Dữ liệu cache cập nhật mỗi 30 phút từ nhà cung cấp.
Trường icloud = null nghĩa là dịch vụ đó chưa hỗ trợ iCloud (nhà cung cấp không bán, hoặc đang tạm tắt) — chỉ thuê được Gmail. Dịch vụ có khối icloud thì gửi "domain": "icloud.com" khi tạo đơn để nhận mail @icloud.com với giá icloud.price.
Ví dụ
curl "https://otpgmail.net/v1/services" \
  -H "Authorization: Bearer og_xxx..."
Response mẫu
{
  "success": true,
  "data": [
    {
      "code": "ig",
      "name": "Instagram",
      "price": 1060,
      "stock": 342,
      "icloud": {
        "price": 950,
        "stock": 120
      }
    },
    {
      "code": "tg",
      "name": "Telegram",
      "price": 530,
      "stock": 1200,
      "icloud": {
        "price": 480,
        "stock": 860
      }
    },
    {
      "code": "fb",
      "name": "Facebook",
      "price": 1590,
      "stock": 88,
      "icloud": null
    }
  ]
}
Lỗi có thể gặp: UNAUTHORIZED
POST/v1/orders
Tạo đơn thuê mail nhận OTP — Gmail (mặc định) hoặc iCloud khi gửi domain: "icloud.com". Trừ tiền ngay khi provider cấp mail thành công. Trả về danh sách đơn (1 hoặc nhiều nếu quantity > 1).
Bắt buộc gửi header Idempotency-Key (UUID). Mỗi lần thuê mới sinh 1 UUID mới; retry sau timeout dùng LẠI key cũ để tránh tạo đơn trùng. Lệnh này phải chờ nhà cung cấp cấp mail nên thường mất khoảng 0,3 giây, nhưng lúc cao điểm có thể lên tới 10 giây (tỉ lệ thấp) — hãy đặt timeout phía client khoảng 15 giây, đừng để 5 giây rồi retry sớm.
Tham số
TênKiểuBắt buộcMô tả
servicestringMã dịch vụ (lấy từ GET /v1/services, ví dụ: "ig", "tg", "fb")
quantitynumberKhôngSố lượng mail cần thuê (mặc định 1, tối đa 50 mỗi lần)
domainstringKhôngLoại mail: "gmail.com" (mặc định) hoặc "icloud.com". Không gửi = gmail.com — hệ thống cũ của bạn không cần sửa gì. Chỉ thuê được iCloud ở dịch vụ có icloud khác null trong GET /v1/services, ngược lại nhận lỗi DOMAIN_UNAVAILABLE. Giá trị khác hai giá trị trên ⇒ VALIDATION_ERROR.
Ví dụ
# Sinh Idempotency-Key ngẫu nhiên mỗi lần tạo đơn MỚI
# Dùng LẠI key cũ khi retry sau timeout (chống đơn trùng)
# domain: "gmail.com" (mặc định, có thể bỏ) | "icloud.com" (thuê mail @icloud.com)
curl -X POST "https://otpgmail.net/v1/orders" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"service":"ig","quantity":1,"domain":"gmail.com"}'
Response mẫu
{
  "success": true,
  "data": [
    {
      "orderId": "abc123xyz",
      "service": "ig",
      "domain": "gmail.com",
      "email": "[email protected]",
      "status": "waiting_code",
      "price": 1060,
      "otp": [],
      "codeDeadlineAt": 1753270000,
      "rentExpiresAt": 1753356400,
      "createdAt": 1753268200
    }
  ]
}
Lỗi có thể gặp: UNAUTHORIZED, VALIDATION_ERROR, INSUFFICIENT_BALANCE, OUT_OF_STOCK, DOMAIN_UNAVAILABLE, NO_MAILS_AVAILABLE, QUANTITY_EXCEEDED, WAITING_LIMIT_REACHED, DUPLICATE_REQUEST, MAINTENANCE
GET/v1/orders/{id}
Lấy chi tiết đơn thuê theo ID, bao gồm danh sách OTP đã nhận (otp[]). Poll endpoint này mỗi 3–5 giây để lấy mã khi đơn ở trạng thái waiting_code.
Mảng otp[] xếp theo thứ tự nhận: cũ trước, MỚI NHẤT Ở CUỐI — lấy mã mới nhất bằng otp[otp.length - 1]. Sau khi có mã đầu tiên, hệ thống TỰ ĐỘNG mở sẵn để nhận mã tiếp theo — bạn không cần gọi thêm lệnh nào. Cứ tiếp tục poll endpoint này, có mã mới là nó tự được thêm vào cuối otp[] (miễn phí, trong 24h kể từ khi thuê). Nếu dịch vụ chỉ cho phép 1 mã cho mỗi mail thì otp[] sẽ dừng lại ở mã đó, phản hồi vẫn bình thường, không có lỗi.
Tham số
TênKiểuBắt buộcMô tả
idstringID đơn thuê (orderId trả về lúc tạo)
Ví dụ
curl "https://otpgmail.net/v1/orders/ORDER_ID" \
  -H "Authorization: Bearer og_xxx..."
Response mẫu
{
  "success": true,
  "data": {
    "orderId": "abc123xyz",
    "service": "ig",
    "domain": "gmail.com",
    "email": "[email protected]",
    "status": "completed",
    "price": 1060,
    "otp": [
      {
        "code": "123456",
        "receivedAt": 1753268500
      },
      {
        "code": "789012",
        "receivedAt": 1753269000
      }
    ],
    "codeDeadlineAt": 1753270000,
    "rentExpiresAt": 1753356400,
    "createdAt": 1753268200
  }
}
Lỗi có thể gặp: UNAUTHORIZED, NOT_FOUND
POST/v1/orders/{id}/cancel
Hủy đơn thuê và hoàn 100% tiền. Chỉ được hủy khi đơn đang ở trạng thái waiting_code VÀ chưa nhận được OTP nào.
Đơn đã có OTP (dù 1 mã) sẽ không được hủy và không hoàn tiền — hành vi này áp dụng cả trên web lẫn API.
Tham số
TênKiểuBắt buộcMô tả
idstringID đơn thuê cần hủy
Ví dụ
curl -X POST "https://otpgmail.net/v1/orders/ORDER_ID/cancel" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Content-Type: application/json"
Response mẫu
{
  "success": true,
  "data": {
    "orderId": "abc123xyz",
    "service": "ig",
    "domain": "gmail.com",
    "email": "[email protected]",
    "status": "cancelled",
    "price": 1060,
    "otp": [],
    "codeDeadlineAt": 1753270000,
    "rentExpiresAt": 1753356400,
    "createdAt": 1753268200
  }
}
Lỗi có thể gặp: UNAUTHORIZED, NOT_FOUND, ORDER_NOT_CANCELLABLE

Vòng đời đơn thuê

Trạng tháiMô tả
Chờ mãĐơn mới tạo, đang đợi OTP đầu tiên. Poll GET /v1/orders/{id} mỗi 3–5 giây.
Hoàn thànhNhận được OTP đầu tiên — chuyển ngay lập tức. Vẫn tự nhận thêm mã miễn phí đến hết 24h, cứ poll tiếp là mã mới vào cuối otp[].
Đã hủyHoàn 100% tiền. Xảy ra khi: user gọi /cancel (chưa có OTP), hoặc đơn tự hủy sau 30 phút không nhận được mã.
Lưu ý quan trọng:
  • Poll GET /v1/orders/{id} mỗi 3–5 giây khi đơn đang waiting_code để lấy OTP kịp thời.
  • Nhận được OTP đầu tiên ⇒ status chuyển sang completed ngay lập tức.
  • Sau 30 phút không có mã ⇒ hệ thống tự hủy và hoàn 100% tiền (status = cancelled).
  • Mảng otp[] xếp cũ trước, mới nhất ở cuối. Lấy mã mới nhất bằng otp[otp.length - 1] (Python: otp[-1]).
  • Đơn completed nhận thêm OTP miễn phí trong 24h kể từ lúc tạo, và tự động — không cần gọi thêm lệnh nào. Ngay sau mỗi mã, hệ thống đã mở sẵn để chờ mã kế tiếp. Cứ tiếp tục poll GET /v1/orders/{id}, có mã mới là nó tự xuất hiện ở cuối otp[].
  • Nếu dịch vụ chỉ cho phép 1 mã cho mỗi mail, otp[] sẽ dừng ở mã đó. Phản hồi vẫn bình thường, không có lỗi — bên bạn tự quyết khi nào ngừng poll.
  • Lệnh thuê POST /v1/orders phải chờ nhà cung cấp cấp mail nên thường mất ~0,3 giây, nhưng lúc cao điểm có thể lên tới 10 giây (tỉ lệ thấp). Đặt timeout ≈ 15 giây phía client, đừng để 5 giây rồi retry sớm — retry nhớ dùng lại Idempotency-Key cũ.
  • Đơn đã có OTP không thể hủy và không hoàn tiền — nút hủy sẽ trả lỗi ORDER_NOT_CANCELLABLE.
  • Thuê mail @icloud.com: gửi "domain": "icloud.com" khi tạo đơn (bỏ trống = Gmail, bot cũ không cần sửa). Dịch vụ không hỗ trợ iCloud hoặc iCloud đang tạm tắt ⇒ lỗi DOMAIN_UNAVAILABLE — đổi sang Gmail là thuê được ngay. Vòng đời, giá hủy/hoàn tiền, cách lấy mã của đơn iCloud giống hệt Gmail.

Rate Limit

Giới hạn áp dụng theo từng API key:
  • 10 request/giây — bùng request nhanh trong vài giây
  • 300 request/phút — tổng lưu lượng mỗi phút
Vượt giới hạn ⇒ HTTP 429 + header Retry-After: <số giây> + body {"success":false,"error":{"code":"RATE_LIMITED",...}}. Chờ đủ số giây trong header trước khi thử lại.

Bảng mã lỗi

Mọi lỗi đều có cấu trúc: {"success":false,"error":{"code":"...","message":"..."}}
Mã lỗiHTTPÝ nghĩa
UNAUTHORIZED401API key không hợp lệ, thiếu key, hoặc tài khoản đang bị khóa.
VALIDATION_ERROR400Tham số gửi lên không hợp lệ (sai kiểu, thiếu trường bắt buộc, v.v.).
INSUFFICIENT_BALANCE402Số dư tài khoản không đủ để thanh toán đơn thuê.
OUT_OF_STOCK409Dịch vụ hết mail khả dụng (theo loại mail đã chọn) tại thời điểm thuê.
DOMAIN_UNAVAILABLE409Dịch vụ không bán loại mail đã chọn — chưa hỗ trợ iCloud, hoặc iCloud đang tạm tắt. Gửi domain "gmail.com" (hoặc bỏ trường này) để thuê Gmail.
NO_MAILS_AVAILABLE503Nhà cung cấp không còn mail cho dịch vụ này (hết tạm thời).
QUANTITY_EXCEEDED400Số lượng quantity vượt giới hạn tối đa (50/lần).
WAITING_LIMIT_REACHED429Đang có quá nhiều đơn Chờ mã đồng thời (tối đa 100 đơn waiting_code/tài khoản).
ORDER_NOT_CANCELLABLE409Đơn không thể hủy — có thể đã có OTP, hoặc không còn ở trạng thái waiting_code.
RATE_LIMITED429Vượt giới hạn 10 req/giây hoặc 300 req/phút. Header Retry-After cho biết số giây cần chờ.
DUPLICATE_REQUEST409Idempotency-Key đã dùng với payload khác. Sinh key mới để tạo đơn khác.
PROVIDER_ERROR502Lỗi từ nhà cung cấp mail (tạm thời — thử lại sau vài giây).
MAINTENANCE503Hệ thống đang bảo trì — mọi thao tác tạo/hủy đơn bị tạm dừng.