Ba endpoint, JSON vào và JSON ra. Không cần khóa, không cần tài khoản trên các tên miền
công khai — dán một yêu cầu vào terminal và nó hoạt động.
Tổng quan
Một hộp thư không bao giờ được tạo ra — nó tồn tại ngay khi một thư đến một
địa chỉ, và biến mất 5 ngày sau đó. Không có
gì để đăng ký, nên trên các tên miền công khai API không có khái niệm
người dùng, dự án hay token.
Mọi phản hồi đều là JSON, kể cả mọi lỗi.
Mọi thời gian đều theo UTC ở dạng RFC 3339 — 2026-08-04T18:31:07Z.
ID tin nhắn là chuỗi không có ý nghĩa cụ thể. Đừng phân tích chúng.
Chỉ nhận. Không có endpoint nào để gửi thư, đây là chủ đích thiết kế.
URL cơ sở
https://grabmail.io/api/v1
Chỉ HTTPS; HTTP thuần được chuyển hướng. Phiên bản nằm trong đường dẫn, và
v1 sẽ không thay đổi cấu trúc bất ngờ — một thay đổi phá vỡ tương thích sẽ nhận
một số mới.
Xác thực: không cần
Không có gì trên các tên miền công khai. Bất kỳ ai biết một địa chỉ đều có thể
đọc hộp thư của nó, qua API cũng như qua trang web. Đó là
thỏa thuận của một dịch vụ dùng chung, tạm thời, nên đừng bao giờ gắn địa chỉ công khai
cho bất cứ điều gì bạn quan tâm.
Một tên miền bạn trỏ về đây sẽ trả lời qua cùng các endpoint này, cũng không cần khóa
nào cả. Trỏ MX về chúng tôi và thư đầu tiên sẽ kết nối nó; xem
kết nối một tên miền. Các hộp thư trên đó có thể được đọc bởi bất kỳ ai biết địa chỉ,
giống hệt như các tên miền công khai.
Thông tin xác thực duy nhất trong API này là khóa của tài khoản bạn, được mô tả bên dưới — một khóa với tài khoản miễn phí, nhiều hơn với gói trả phí. Khóa không có cấp riêng: mỗi lệnh gọi được xét theo gói mà tài khoản của nó đang có vào lúc đó, nên cùng một khóa sẽ thoát khỏi các giới hạn miễn phí và mở nhóm premium ngay khi bạn đăng ký, rồi trở về hạn mức miễn phí khi gói kết thúc. Các tên miền công khai không cần khóa; gửi kèm với chúng, khóa sẽ tính các lệnh gọi cho tài khoản của bạn thay vì cho địa chỉ IP. Một khóa được gửi mà không xác định hoặc đã bị thu hồi sẽ nhận 401 kèm unauthorized trên mọi endpoint, bất kể tên miền — để một lỗi gõ nhầm hiện ra ngay lập tức thay vì trông như một hộp thư trống.
Tên miền premium
Ngoại lệ duy nhất của quy tắc trên. Các tên miền công khai
nằm trong danh sách chặn thư dùng một lần, nên biểu mẫu đăng ký
đôi khi từ chối địa chỉ trên đó. Gói trả phí mở một pool gồm
97 tên miền .com riêng, được giữ ngoài các danh sách đó.
API không thay đổi gì cả. Cùng đường dẫn, cùng tham số, cùng dạng phản hồi. Khác biệt duy nhất là một header: địa chỉ premium được đọc bằng Authorization: Bearer gm_live_…, dùng khóa từ khóa API của bạn. Không có khóa từ gói trả phí, cùng yêu cầu đó trả về 404 — đúng từng chữ là câu trả lời cho một tên miền chúng tôi không lưu trữ, một cách cố ý, để nhóm không thể bị liệt kê bằng cách đoán tên. Không bao giờ là hộp thư.
Tên miền của nhóm nằm ở đâu
GET /api/v1/domains cùng khóa của bạn trả về các tên miền công khai và tên miền của nhóm. Cùng lệnh gọi đó không kèm khóa — hoặc với khóa từ một tài khoản miễn phí hoặc đã hết hạn — trả về các tên miền công khai, nhóm có bao nhiêu tên miền và giá bao nhiêu, nhưng không bao giờ có một cái tên: giữ chúng ngoài danh sách chặn thư dùng một lần chính là thứ gói này mua được. Người đăng ký đã đăng nhập cũng thấy nhóm này trong bộ chọn tên miền trên trang chủ.
GET /api/v1/me là lệnh gọi duy nhất tự nó đánh giá một khóa: 200 kèm gói, kỳ hiện tại, hạn mức đã dùng và còn lại, các địa chỉ đang giữ và giới hạn tần suất của bạn — hoặc 401unauthorized nếu khóa không xác định hoặc đã bị thu hồi. Hãy gọi lệnh này trước khi có gì đó trên nhóm trả về 404: câu trả lời đó cố ý giấu đi một vấn đề về khóa, còn lệnh này thì cho thấy nó.
Từng trường hợp, kèm theo lý do của nó. Hai trường hợp đầu tiên trông có vẻ bất ngờ, cho đến khi lý do được đọc.
404
unknown_domain — không có khóa, hoặc khóa từ một tài khoản miễn phí hay đã hết hạn. Giống hệt câu trả lời cho một tên miền chúng tôi không lưu trữ, một cách cố ý: phân biệt hai trường hợp đó sẽ khiến nhóm có thể bị liệt kê bằng cách đoán tên. Hãy kiểm tra khóa bằng /api/v1/me.
401
unauthorized — khóa được gửi không xác định hoặc đã bị thu hồi. Được trả về trên mọi endpoint, bất kể tên miền: nó nói về khóa, không bao giờ nói về một tên miền.
402
quota_reached — hạn mức của kỳ này đã hết và tính năng vượt hạn mức đang tắt. overage_cap / overage_funds — tính năng vượt hạn mức đang bật, nhưng mức trần bạn đặt đã đạt tới hoặc số dư không đủ. Các địa chỉ đã giữ trước đó vẫn hoạt động bình thường trong cả ba trường hợp.
403
address_taken — một người đăng ký khác đang giữ địa chỉ đó. Hãy chọn một tên khác.
409
address_limit — dành riêng cho một gói giới hạn số địa chỉ. Hiện chưa gói nào làm vậy.
429
rate_limited — ở gói miễn phí (không có khóa, hoặc với khóa miễn phí), quá 60 yêu cầu mỗi phút, hoặc hơn một lượt đọc mỗi giây trên một địa chỉ; với khóa trả phí, hơn 2, 3 hoặc 5 lượt đọc mỗi giây trên một địa chỉ. daily_limit_reached — đã dùng hết 1.000 yêu cầu miễn phí trong ngày. Gói trả phí không có giới hạn theo phút, cũng không có giới hạn theo ngày. Cả hai lỗi đều kèm Retry-After.
Địa chỉ đang giữ và hạn mức
Một địa chỉ premium được giữ bởi tài khoản đầu tiên đọc nó bằng khóa hợp lệ — bất kỳ lượt đọc nào, trên bất kỳ endpoint nào hoặc qua MCP, không có gì cần đặt trước. Trong lúc đang giữ, chỉ tài khoản đó mới đọc được nó; bất kỳ ai khác đều nhận 403. Địa chỉ vẫn được giữ cho đến khi bạn trả lại từ bảng điều khiển, hoặc gói kết thúc — vào ngày hết hạn, không có thời gian ân hạn.
Hạn mức tính theo đơn vị: một thư nhận được ở một địa chỉ premium hoặc một địa chỉ premium mới được mở, tùy cái nào đến trước — nên một địa chỉ bạn mở mà không bao giờ đọc vẫn tốn một đơn vị. Đọc lại một địa chỉ đang giữ thì miễn phí. Không gói nào giới hạn số địa chỉ một tài khoản đang giữ; hạn mức mới là thứ giới hạn nó, và /api/v1/me cho biết còn lại bao nhiêu.
Bí danh, cả trên địa chỉ premium
Mỗi hộp thư liệt kê một alias: một địa chỉ thứ hai chuyển thư vào cùng hộp thư đó mà không tiết lộ gì về nó. Hãy đưa bí danh đó cho một biểu mẫu và thăm dò địa chỉ; ai giữ bí danh đó cũng chỉ thấy một hộp thư trống, luôn luôn. Nó không đổi với một địa chỉ nhất định, miễn phí, và cũng được trả về cho địa chỉ premium y hệt như cho địa chỉ công khai. Tên miền của nó là một trong các tên miền của chúng tôi và cố ý không được liệt kê ở bất kỳ đâu.
Toàn bộ, trong bốn lệnh gọi
KEY="gm_live_…" # từ trang khóa API của bạn, với một gói trả phí
# 1. Kiểm tra khóa: gói, hạn mức còn lại, giới hạn tần suất. 401 nếu khóa sai.
curl -s https://grabmail.io/api/v1/me -H "Authorization: Bearer $KEY"
# 2. Liệt kê nhóm. Tên miền chỉ có trong phản hồi khi dùng khóa trả phí.
curl -s https://grabmail.io/api/v1/domains -H "Authorization: Bearer $KEY"
# 3. Đọc một hộp thư trên một trong số đó. Lượt đọc đầu tiên này giữ địa chỉ và tính một đơn vị.
curl -sG https://grabmail.io/api/v1/mailbox -H "Authorization: Bearer $KEY" \
--data-urlencode "address=a7f3k2@one-of-the-pool.com"
# 4. Đọc một thư, cùng header.
curl -sG https://grabmail.io/api/v1/message/MESSAGE_ID -H "Authorization: Bearer $KEY" \
--data-urlencode "mailbox=a7f3k2@one-of-the-pool.com"
Các tên miền công cộng và tên miền của riêng bạn vẫn miễn phí, không cần khóa và không giới hạn ở mọi gói, kể cả gói miễn phí. Hạn mức chỉ tính nhóm premium và không gì khác. Các gói và giá có trên trang các gói.
Các endpoint
GET/api/v1/mailbox
Mọi thứ đang chờ tại một địa chỉ, mới nhất trước. Đây là lệnh gọi mà bộ kiểm thử của bạn liên tục thăm dò.
Tham số
Tên
Vào
Loại
Bắt buộc
Mô tả
address
query
string
có
Hộp thư cần đọc, ví dụ k7fq2m@grabmail.io.
limit
query
integer
không
Số lượng tin nhắn trả về trong lần gọi này, 1–200. Mặc định là 50, mới nhất trước. Giới hạn này áp dụng cho một phản hồi, không phải toàn bộ hộp thư — dùng before để đọc các tin trước đó.
before
query
string
không
id của tin nhắn cũ nhất mà bạn đã có; trả về trang tiếp theo sau nó. Truyền lại trường next từ phản hồi trước đó. Khi next là null, bạn đã có tất cả.
Hộp thư đã được đọc. Hộp thư rỗng vẫn trả về 200 với count: 0, không bao giờ là 404. next mang con trỏ cho trang tiếp theo, hoặc null khi đã hết. alias là một địa chỉ thứ hai chuyển thư tới đây mà không tiết lộ gì về địa chỉ này — hãy đưa nó cho một biểu mẫu thay vì address; ai giữ nó cũng chỉ thấy một hộp thư trống, luôn luôn. Nó không đổi, miễn phí, và cũng được trả về cho địa chỉ premium.
400
Địa chỉ không đúng định dạng, hoặc before không phải là id tin nhắn.
400
address bị thiếu hoặc không phải là địa chỉ hợp lệ.
401
Một khóa API đã được gửi và khóa đó không xác định hoặc đã bị thu hồi. Một khóa sai bị từ chối trên mọi tên miền; các tên miền công khai không cần khóa nào cả.
402
Chỉ trên nhóm premium: hạn mức của gói đã hết — quota_reached, hoặc overage_cap / overage_funds khi tính năng vượt hạn mức đang bật. Các địa chỉ đã giữ trước đó vẫn hoạt động.
403
Chỉ trên nhóm premium: một người đăng ký khác đang giữ địa chỉ đó (address_taken).
404
Tên miền đó không được lưu trữ tại đây — kiểm tra bản ghi MX. Một tên miền thuộc nhóm premium được đọc mà không có khóa từ gói trả phí sẽ cố ý nhận đúng câu trả lời này.
429
Đã vượt quá giới hạn tần suất. Hãy thử lại sau khoảng thời gian trong Retry-After.
GET/api/v1/message/{id}
Tiêu đề thư, phần văn bản thuần, phần HTML và mọi tệp đính kèm.
Đã xóa. Lệnh gọi này là idempotent: xóa hai lần vẫn trả về 200.
400
mailbox bị thiếu hoặc không hợp lệ.
404
Không có tin nhắn nào trong hộp thư đó.
429
Đã vượt quá giới hạn tần suất.
Tệp đính kèm
Mọi thư đều liệt kê tệp đính kèm của nó cùng một URL đã dựng sẵn. Hãy lấy tệp bằng
cùng cách xác thực như với chính thư đó.
GET /api/v1/attachment/{id}?mailbox={address}
Nó luôn trả về application/octet-stream kèm
Content-Disposition: attachment, dù người gửi gắn nhãn gì đi nữa. Đó là
cố ý: lặp lại text/html của người lạ
sẽ cho phép một tệp đính kèm chạy như một trang trên chính nguồn gốc này. Loại thật nằm trong
JSON của thư, nơi nó là dữ liệu chứ không phải chỉ thị.
Lỗi
Mọi lỗi đều là JSON với cùng hai trường, nên client xử lý chúng
ở một nơi duy nhất. Mã trạng thái mang loại lỗi, error là một
slug ổn định để máy đọc, và message dành cho con người và
có thể được viết lại bất cứ lúc nào.
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_address",
"message": "address must look like name@domain"
}
Đừng bao giờ rẽ nhánh dựa trên message. Các slug đang dùng là invalid_address, bad_cursor, unknown_domain, not_found, rate_limited, daily_limit_reached, unauthorized và, chỉ riêng trên nhóm premium, quota_reached, overage_cap, overage_funds, address_taken và address_limit.
Một số lỗi mang nhiều hơn hai trường đó: một hint nói nên làm gì, một liên kết docs, ở 404 và 429 một khối premium_pool chứa giá của nhóm và cách mở khóa nó, và ở 429 do chạm giới hạn miễn phí, một khối upgrade cho biết gói trả phí gỡ bỏ những giới hạn nào — được viết cho một trợ lý đọc nội dung phản hồi thay mặt ai đó, để nó có thể chuyển tiếp lựa chọn đó thay vì bỏ cuộc.
Giới hạn tần suất
Miễn phí, khi không dùng khóa: 60 yêu cầu mỗi phút và 1.000 yêu cầu mỗi ngày, cho mỗi địa chỉ IP. Mọi lệnh gọi tới một hộp thư đều được tính — liệt kê hộp thư, đọc một thư, phần thân HTML của thư, một tệp đính kèm, một lần xóa — và mọi lệnh gọi công cụ MCP cũng vậy. Bộ đếm theo ngày được đặt lại lúc 00:00 UTC.
Với một khóa API miễn phí, cùng hạn mức đó đi theo tài khoản của bạn thay vì địa chỉ IP — tiện khi lệnh gọi của bạn đến từ các địa chỉ thay đổi, như một CI runner. Tài khoản miễn phí có một khóa, và các hộp thư khóa đọc được liệt kê trong hộp thư của bạn. Tạo khóa miễn phí
Trong phạm vi đó, một lượt đọc mỗi giây cho mỗi địa chỉ: thăm dò một hộp thư mỗi giây một lần là nhịp độ dự kiến.
Gói trả phí không bị giới hạn theo phút, cũng không bị giới hạn theo ngày. Gửi khóa của gói trả phí dưới dạng Authorization: Bearer và chỉ còn lại tốc độ theo từng địa chỉ của gói — 2, 3 hoặc 5 yêu cầu mỗi giây, trên mọi tên miền, tính theo từng tài khoản. Premium chỉ từ $12,99 mỗi tháng. Xem các gói
Hộp thư trên trang này không trừ vào hạn mức API miễn phí: một trang để mở sẽ tiếp tục kiểm tra thư mới bao lâu tùy bạn cần.
Vượt giới hạn, bạn sẽ nhận 429 kèm header Retry-After tính bằng giây tròn: rate_limited cho giới hạn theo phút hoặc theo địa chỉ, daily_limit_reached cho giới hạn theo ngày, kèm thời gian còn lại đến nửa đêm UTC. Mỗi phản hồi cho yêu cầu miễn phí đều cho biết bạn còn lại bao nhiêu: X-RateLimit-Remaining cho phút hiện tại, X-RateLimit-Daily-Remaining cho ngày hiện tại.
Thời gian lưu trữ
Một thư bị xóa 5 ngày
sau khi đến, dù đã đọc hay chưa. Mọi thư đều mang
expires_at, nên bạn không bao giờ phải tự tính ngày đó.
Đây là giới hạn cứng, không phải một tùy chọn — không tham số nào kéo dài nó. Nếu một thư
cần tồn tại lâu hơn khung thời gian đó, hãy lấy về và lưu trữ ở phía bạn.
Tên miền riêng của bạn
Trỏ MX của bạn tới smtp.grabmail.io và mọi địa chỉ trên
tên miền của bạn sẽ trả lời qua cùng các endpoint này — không có API thứ hai để học,
không cần đăng ký, và không cần khóa.