xmail.API
Tài liệu API

API cho công cụ tự động

Tạo hộp thư, đọc thư và lấy mã xác minh bằng script. Công cụ đã viết cho mail-api v1 chỉ cần đổi base URL và API key.

Base URLhttps://webmail-cloudflare-api-key.replit.app/api/v1

Xác thực

Gửi header Authorization: Bearer <API key>. Key có dạng mk_live_<12 hex>_<secret> và được tạo tại trang quản trị API keys. Header X-API-Key: <key> cũng được chấp nhận. Mỗi key có scopes và giới hạn số request mỗi phút.

Lỗi

Mọi lỗi đều trả JSON {"detail": "..."}.

401Thiếu key, key sai, hết hạn hoặc đã thu hồi
403Thiếu scope, hoặc hộp thư bị tắt / hết hạn
404Không tìm thấy / chưa có mã
408Đã kiểm tra nhưng hết thời gian chờ mã
409Chưa cấu hình IMAP, hoặc UIDVALIDITY đã đổi — tải lại danh sách
413Vượt giới hạn kích thước thư / dữ liệu IMAP
422Tham số không hợp lệ, hoặc cần thu hẹp sender/after để giảm số thư phải quét
429Vượt giới hạn tốc độ / kết nối (xem header Retry-After)
502IMAP lỗi kết nối, đăng nhập, TLS hoặc giao thức — không chuyển sang thư cục bộ
503Cần nhập lại thông tin IMAP đã lưu
504IMAP chưa hoàn thành lần kiểm tra nào trước thời hạn

Tham số mailbox_id

{mailbox_id} nhận UUID của hộp thư hoặc địa chỉ email đầy đủ. Với nguồn cục bộ và catch-all, địa chỉ chưa từng được tạo sẽ trả danh sách [], còn codes/wait chờ thư đầu tiên (hộp thư được tạo khi thư tới). Nguồn IMAP cần hộp thư đã tồn tại và được quản trị viên cấu hình kết nối thật.

Chọn nguồn IMAP hoặc cục bộ

Bốn API liệt kê thư, đọc thư, codes/latest và codes/wait nhận source=local|imap. Bỏ qua tham số này vẫn đọc nguồn cục bộ qua Worker như trước. Không tự chuyển nguồn khi IMAP lỗi. Cấu hình IMAP tại Quản trị → Đọc thư IMAP; API key không được xem mật khẩu hay sửa cấu hình. xmail chỉ nhận thư, không có API gửi thư.

Với IMAP, danh sách và mã xác minh nhận folder là đường dẫn thư mục chính xác, mặc định INBOX. Kết quả có source: "imap" và folder. Dùng nguyên id hoặc message_id trả về, mã hóa URL khi đưa vào đường dẫn: mã thư bao gồm hộp thư, thư mục, UIDVALIDITY và UID, không chỉ là UID. Lỗi 409 do UIDVALIDITY đổi yêu cầu lấy mã thư mới. Token hộp thư vẫn chỉ đọc được hộp thư của chính nó; quyền API key vẫn là messages:read hoặc codes:read tương ứng.

IMAP chỉ đọc, không đánh dấu đã đọc. API xét thông tin của tối đa 1.000 UID mới nhất khớp tìm kiếm người gửi/ngày, lọc chính xác sender và after rồi đọc tối đa 100 nội dung thư để trích mã, lọc length. Mã có thời điểm nhận INTERNALDATE mới nhất trong cửa sổ đó được chọn. Nếu chưa tìm được mã nhưng còn thư ngoài giới hạn, API trả 422 để bạn thu hẹp bộ lọc. Giới hạn 10 MiB/thư, 25 MiB/yêu cầu và 45 giây cho lượt đọc thường; giảm limit hoặc thu hẹp bộ lọc khi vượt giới hạn.

codes/wait giữ một kết nối, kiểm tra mỗi 3 giây và đóng ngay khi khách ngắt yêu cầu. timeout 1–60 giây tính cả bước kết nối. Tối đa 4 kết nối/hộp thư và 20 kết nối trên mỗi tiến trình, dùng chung với webmail; quá giới hạn trả 429. Hãy truyền after là thời điểm bắt đầu thao tác để tránh lấy mã cũ.

bash
# Hộp thư này phải được cấu hình IMAP trước
curl --max-time 40 "https://webmail-cloudflare-api-key.replit.app/api/v1/mailboxes/signup-01@example.com/codes/wait?source=imap&folder=INBOX&timeout=30&sender=github&length=6&after=$(date +%s)" \
  -H "Authorization: Bearer $MAIL_API_KEY"

# Liệt kê thư IMAP, sau đó dùng id trả về để đọc nội dung
curl "https://webmail-cloudflare-api-key.replit.app/api/v1/mailboxes/signup-01@example.com/messages?source=imap&folder=INBOX&limit=10" \
  -H "Authorization: Bearer $MAIL_API_KEY"
javascript
// imapId = id từ danh sách, hoặc message_id từ codes/latest / codes/wait
const url = `https://webmail-cloudflare-api-key.replit.app/api/v1/mailboxes/${encodeURIComponent(address)}/messages/${encodeURIComponent(imapId)}?source=imap`;
const message = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.MAIL_API_KEY}` }
}).then(async r => {
  if (!r.ok) throw new Error(await r.text());
  return r.json();
});

Lưu trữ thư

Mỗi thư cục bộ tự bị xoá 30 phút sau khi nhận, trừ khi chính thư đó được đánh dấu lưu (is_kept, nút Lưu thư trong webmail). Việc lưu áp dụng cho từng thư; không có tuỳ chọn lưu cho cả hộp thư hay tên miền. Mỗi thư có auto_delete_at (thời điểm sẽ xoá, hoặc null khi đã lưu). Sau khi bị xoá, thư trả về 404. Thư IMAP nằm trên máy chủ mail, không được sao chép vào kho cục bộ và không bị cơ chế 30 phút này xoá. API IMAP luôn trả auto_delete_at: null; is_kept: false không phải lệnh xoá hay cờ lưu trên máy chủ IMAP.

Endpoints

POST/mailboxesmailboxes:create

Tạo hộp thư. Body {domain?, prefix?, password?, expires_in?}. 201 trả về {id, domain_id, address, status, expires_at, created_at, password, recovery_key, access_token, token_expires_at}. 409 nếu địa chỉ đã tồn tại.

GET/mailboxes/{mailbox_id}mailboxes:read

Thông tin hộp thư kèm message_count, unread_count, last_message_at.

GET/mailboxes/{mailbox_id}/messages?limit=20messages:read

Danh sách MessageSummary mới nhất trước (limit 1-100), mỗi thư kèm mã đã trích xuất, is_kept và auto_delete_at. Thêm source=imap&folder=INBOX để đọc nguồn IMAP.

GET/mailboxes/{mailbox_id}/messages/{message_id}messages:read

MessageDetail gồm text_body, sanitized_html_body, codes, verification_links. Đọc mã thư IMAP phải kèm source=imap; thư mục đã nằm trong mã thư.

GET/mailboxes/{mailbox_id}/codes/latest?sender=&after=&length=codes:read

Trả {code, confidence, context, message_id, sender_address, subject, received_at}; 404 nếu chưa có. sender = chuỗi con của địa chỉ gửi; after = thời điểm ISO-8601 hoặc unix giây; length = độ dài chính xác của mã.

GET/mailboxes/{mailbox_id}/codes/wait?timeout=30&sender=&after=&length=codes:read

Chờ tối đa timeout giây (1-60) rồi trả cùng body như latest, hoặc 408 khi hết thời gian. Mẹo: truyền after = thời điểm bạn kích hoạt email để không nhận mã cũ; đặt timeout của HTTP client lớn hơn timeout chờ.

Script đóng vai một hộp thư

POST /auth/mailbox/login với {email, password} trả về {access_token, token_type: "bearer", expires_at, mailbox}. Sau đó gọi GET /mailbox/me, GET /mailbox/me/messages, GET|DELETE /mailbox/me/messages/{message_id}, GET /mailbox/me/codes/latest với Authorization: Bearer <access_token>. Khôi phục: POST /auth/mailbox/recover với {email, recovery_key, new_password?}.

Để đọc IMAP bằng token này, gọi các đường dẫn /mailboxes/{địa chỉ của bạn}/…?source=imap ở trên. Các API /mailbox/me/messages cũ vẫn chỉ đọc thư cục bộ.

Ví dụ

Tạo hộp thư

bash
curl -X POST https://webmail-cloudflare-api-key.replit.app/api/v1/mailboxes \
  -H "Authorization: Bearer $MAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prefix": "signup-01", "expires_in": 3600}'

Liệt kê thư

bash
curl "https://webmail-cloudflare-api-key.replit.app/api/v1/mailboxes/signup-01@example.com/messages?limit=20" \
  -H "Authorization: Bearer $MAIL_API_KEY"

Mã mới nhất

bash
curl "https://webmail-cloudflare-api-key.replit.app/api/v1/mailboxes/signup-01@example.com/codes/latest?sender=github&length=6" \
  -H "Authorization: Bearer $MAIL_API_KEY"

Chờ mã

bash
curl --max-time 40 "https://webmail-cloudflare-api-key.replit.app/api/v1/mailboxes/signup-01@example.com/codes/wait?timeout=30&after=$(date +%s)" \
  -H "Authorization: Bearer $MAIL_API_KEY"

Luồng đầy đủ với Python

python
import time
import requests

BASE = "https://webmail-cloudflare-api-key.replit.app/api/v1"
HEADERS = {"Authorization": "Bearer mk_live_xxxxxxxxxxxx_yourSecret"}

# 1. Create a mailbox
r = requests.post(f"{BASE}/mailboxes", json={"expires_in": 3600}, headers=HEADERS, timeout=15)
r.raise_for_status()
mailbox = r.json()
address = mailbox["address"]
print("Use this address:", address)

# 2. Trigger the sign-up somewhere with that address
trigger_time = int(time.time())
# signup_somewhere(address)

# 3. Wait for the code
code = None
for attempt in range(4):
    r = requests.get(
        f"{BASE}/mailboxes/{address}/codes/wait",
        params={"timeout": 30, "after": trigger_time},
        headers=HEADERS,
        timeout=40,  # must be longer than the wait timeout
    )
    if r.status_code == 408:
        continue  # timed out, try again
    r.raise_for_status()
    code = r.json()["code"]
    break

print("Verification code:", code)

Node (fetch)

javascript
const BASE = "https://webmail-cloudflare-api-key.replit.app/api/v1";
const headers = { Authorization: `Bearer ${process.env.MAIL_API_KEY}` };

const after = Math.floor(Date.now() / 1000);
const res = await fetch(`${BASE}/mailboxes/${encodeURIComponent(address)}/codes/wait?timeout=30&after=${after}`, { headers });
if (res.status === 408) console.log("No code yet, retry");
else console.log((await res.json()).code);