Tiga endpoint, JSON masuk dan JSON keluar. Tanpa kunci dan tanpa akun pada domain
publik — tempel permintaan ke terminal dan langsung berfungsi.
Ikhtisar
Kotak masuk tidak pernah dibuat — ia ada begitu sebuah pesan tiba di suatu
alamat, dan hilang 5 hari kemudian. Tidak ada
yang perlu didaftarkan, jadi pada domain publik API tidak mengenal konsep
pengguna, proyek, atau token.
Setiap respons berupa JSON, termasuk setiap error.
Semua waktu dalam UTC dengan format RFC 3339 — 2026-08-04T18:31:07Z.
Id pesan adalah string opak. Jangan diurai.
Hanya terima. Tidak ada endpoint untuk mengirim email, memang disengaja.
URL dasar
https://grabmail.io/api/v1
Hanya HTTPS; HTTP biasa akan dialihkan. Versi berada di path, dan
v1 tidak akan berubah bentuk di bawah Anda — perubahan yang tidak kompatibel akan
mendapat nomor baru.
Autentikasi: Tidak Diperlukan
Tidak ada di domain publik. Siapa pun yang mengetahui suatu alamat dapat
membaca kotak masuknya, melalui API sama seperti melalui situs web. Itulah
konsekuensi dari layanan email sekali pakai bersama, jadi jangan pernah gunakan
hal yang penting bagi Anda di alamat publik.
Domain yang Anda arahkan ke sini akan dijawab lewat endpoint yang sama, tanpa kunci
juga. Arahkan MX-nya ke kami dan pesan pertama akan menghubungkannya; lihat
menghubungkan domain. Kotak masuk di dalamnya dapat dibaca oleh siapa pun yang mengetahui alamatnya,
persis seperti domain publik.
Satu-satunya kredensial dalam API ini adalah kunci akun Anda, yang dijelaskan di bawah — satu untuk akun gratis, lebih banyak di paket berbayar. Kunci tidak punya tingkatan sendiri: setiap panggilan dinilai berdasarkan paket yang dimiliki akunnya saat itu, sehingga kunci yang sama lepas dari batas gratis dan membuka kumpulan premium begitu Anda berlangganan, lalu kembali ke kuota gratis saat paket berakhir. Domain publik tidak memerlukan kunci; jika dikirim bersamanya, kunci menghitung panggilan Anda untuk akun Anda, bukan untuk alamat IP Anda. Kunci yang dikirim dan tidak dikenal atau sudah dicabut akan dijawab 401 dengan unauthorized pada endpoint mana pun, apa pun domainnya — sehingga salah ketik langsung terlihat alih-alih tersamar sebagai kotak masuk yang tampak kosong.
Domain premium
Satu-satunya pengecualian dari aturan di atas. Domain publik
ada di daftar blokir surel sekali pakai, dan karena itu formulir pendaftaran
kadang menolak alamat di domain tersebut. Paket berbayar membuka pool berisi
97 domain .com privat, yang dijauhkan dari daftar itu.
Tidak ada yang berubah di API. Jalur, parameter, dan bentuk respons yang sama. Satu-satunya perbedaan adalah satu header: alamat premium dibaca dengan Authorization: Bearer gm_live_…, memakai kunci dari kunci API Anda. Tanpa kunci dari paket berbayar, permintaan yang sama menjawab 404 — persis sama dengan jawaban untuk domain yang tidak kami host, secara sengaja, agar kumpulan tidak bisa didaftar dengan menebak nama. Tidak pernah kotak masuk.
Di mana domain kumpulan berada
GET /api/v1/domains dengan kunci Anda mengembalikan domain publik dan nama-nama domain milik kumpulan itu. Panggilan yang sama tanpa kunci — atau dengan kunci dari akun gratis atau yang sudah kedaluwarsa — mengembalikan domain publik, berapa banyak domain yang dimiliki kumpulan itu dan berapa biayanya, tetapi tidak pernah sebuah nama: menjauhkannya dari daftar hitam surel sekali pakai itulah yang dibeli oleh paket ini. Pelanggan yang sudah masuk juga melihat kumpulan itu di pemilih domain pada beranda.
GET /api/v1/me adalah satu-satunya panggilan yang menilai sebuah kunci dengan sendirinya: 200 berisi paket, periode saat ini, kuota yang terpakai dan tersisa, alamat yang dipegang, dan batas laju Anda — atau 401unauthorized jika kuncinya tidak dikenal atau sudah dicabut. Panggil ini lebih dulu saat sesuatu di kumpulan menjawab 404: jawaban itu sengaja menyembunyikan masalah kunci, sedangkan yang ini menampakkannya.
Setiap kasus, beserta alasannya. Dua yang pertama tampak mengejutkan sampai alasannya dibaca.
404
unknown_domain — tanpa kunci, atau kunci dari akun gratis atau yang sudah kedaluwarsa. Sama persis dengan jawaban untuk domain yang tidak kami host, secara sengaja: membedakan keduanya akan membuat kumpulan bisa didaftar dengan menebak nama. Periksa kuncinya dengan /api/v1/me.
401
unauthorized — kunci yang dikirim tidak dikenal atau sudah dicabut. Dijawab di endpoint mana pun, apa pun domainnya: ini menyatakan sesuatu tentang kuncinya, bukan tentang sebuah domain.
402
quota_reached — kuota periode ini sudah habis dan fitur melewati kuota sedang mati. overage_cap / overage_funds — fitur melewati kuota sedang aktif, tetapi batas yang Anda tetapkan sudah tercapai atau saldo tidak mencukupi. Alamat yang sudah dipegang tetap berfungsi dalam ketiga kasus ini.
403
address_taken — pelanggan lain sedang memegang alamat itu. Pilih nama lain.
409
address_limit — dicadangkan untuk paket yang membatasi jumlah alamat. Belum ada paket yang melakukannya hari ini.
429
rate_limited — di paket gratis (tanpa kunci, atau dengan kunci gratis), lebih dari 60 permintaan per menit, atau lebih dari satu pembacaan per detik pada satu alamat; dengan kunci berbayar, lebih dari 2, 3, atau 5 pembacaan per detik pada satu alamat. daily_limit_reached — 1.000 permintaan gratis hari ini sudah habis terpakai. Paket berbayar tidak punya batas per menit maupun batas harian. Keduanya menyertakan Retry-After.
Alamat yang dipegang dan kuota
Sebuah alamat premium dipegang oleh akun pertama yang membacanya dengan kunci yang sah — pembacaan apa pun, di endpoint mana pun atau lewat MCP, tidak ada yang perlu dicadangkan lebih dulu. Selama dipegang, hanya akun itu yang bisa membacanya; siapa pun yang lain mendapat 403. Alamat itu tetap dipegang sampai Anda melepaskannya dari dasbor, atau paketnya berakhir — pada tanggal berakhirnya, tanpa masa tenggang.
Kuota menghitung unit: sebuah pesan yang diterima di alamat premium atau sebuah alamat premium baru yang dibuka, mana pun yang lebih dulu terjadi — jadi alamat yang Anda buka dan tidak pernah dibaca tetap memakai satu unit. Membaca ulang alamat yang sudah dipegang itu gratis. Tidak ada paket yang membatasi berapa banyak alamat yang dipegang sebuah akun; kuota itulah yang membatasinya, dan /api/v1/me menunjukkan berapa sisanya.
Alias, juga pada alamat premium
Setiap daftar kotak masuk membawa sebuah alias: alamat kedua yang mengantar ke kotak masuk yang sama dan tidak mengungkap apa pun tentangnya. Berikan alias itu ke sebuah formulir dan poll alamatnya; siapa pun yang memegang alias itu akan melihat kotak masuk kosong, selalu. Alias ini tetap sama untuk alamat tertentu, gratis, dan dikembalikan untuk alamat premium persis seperti untuk alamat publik. Domainnya adalah salah satu milik kami dan sengaja tidak dicantumkan di mana pun.
Semuanya, dalam empat panggilan
KEY="gm_live_…" # dari halaman kunci API Anda, dengan paket berbayar
# 1. Periksa kunci: paket, sisa kuota, batas laju. 401 jika salah.
curl -s https://grabmail.io/api/v1/me -H "Authorization: Bearer $KEY"
# 2. Daftar kumpulan. Nama-namanya hanya ada di jawaban jika memakai kunci berbayar.
curl -s https://grabmail.io/api/v1/domains -H "Authorization: Bearer $KEY"
# 3. Baca kotak masuk pada salah satunya. Pembacaan pertama ini memegang alamatnya dan menghitung satu unit.
curl -sG https://grabmail.io/api/v1/mailbox -H "Authorization: Bearer $KEY" \
--data-urlencode "address=a7f3k2@one-of-the-pool.com"
# 4. Baca satu pesan, header yang sama.
curl -sG https://grabmail.io/api/v1/message/MESSAGE_ID -H "Authorization: Bearer $KEY" \
--data-urlencode "mailbox=a7f3k2@one-of-the-pool.com"
Domain publik dan domain milik Anda tetap gratis, tanpa kunci dan tanpa batas di semua paket, termasuk yang gratis. Kuota hanya menghitung kumpulan premium dan tidak ada yang lain. Paket dan harga ada di halaman paket.
Endpoint
GET/api/v1/mailbox
Semua yang menunggu di suatu alamat, terbaru lebih dulu. Ini panggilan yang dipoll oleh test suite Anda.
Parameter
Nama
Masuk
Jenis
Wajib
Deskripsi
address
query
string
ya
Mailbox yang akan dibaca, mis. k7fq2m@grabmail.io.
limit
query
integer
tidak
Jumlah pesan yang dikembalikan dalam panggilan ini, 1–200. Standarnya 50, terbaru dahulu. Ini membatasi satu respons, bukan mailbox — gunakan before untuk membaca lebih lanjut.
before
query
string
tidak
id dari pesan tertua yang sudah Anda miliki; mengembalikan halaman setelahnya. Kirim kembali kolom next dari respons sebelumnya. Saat next bernilai null, Anda sudah memiliki semuanya.
Mailbox berhasil dibaca. Mailbox kosong menghasilkan 200 dengan count: 0, bukan 404. next membawa kursor untuk halaman berikutnya, atau null di akhir. alias adalah alamat kedua yang mengantar ke sini dan tidak mengungkap apa pun tentang alamat ini — berikan itu ke sebuah formulir, bukan address; siapa pun yang memegangnya akan melihat kotak masuk kosong, selalu. Alias ini tetap sama, gratis, dan dikembalikan untuk alamat premium juga.
400
Alamat tidak valid, atau before bukan id pesan.
400
address tidak ada atau bukan alamat yang valid.
401
Sebuah kunci API telah dikirim dan kunci itu tidak dikenal atau sudah dicabut. Kunci yang salah ditolak di semua domain; domain publik tidak memerlukan kunci sama sekali.
402
Khusus kumpulan premium: kuota paket sudah habis — quota_reached, atau overage_cap / overage_funds saat fitur melewati kuota sedang aktif. Alamat yang sudah dipegang tetap berfungsi.
403
Khusus kumpulan premium: pelanggan lain sedang memegang alamat itu (address_taken).
404
Domain tersebut tidak dihosting di sini — periksa rekod MX. Sebuah domain kumpulan premium yang dibaca tanpa kunci dari paket berbayar sengaja dijawab persis seperti ini.
429
Batas laju terlampaui. Coba lagi setelah jeda pada Retry-After.
GET/api/v1/message/{id}
Header, bagian teks polos, bagian HTML, dan lampiran apa pun.
Dihapus. Panggilan ini idempoten: menghapus dua kali tetap menjawab 200.
400
mailbox tidak ada atau tidak valid.
404
Tidak ada pesan seperti itu di mailbox tersebut.
429
Batas laju terlampaui.
Lampiran
Setiap pesan mencantumkan lampirannya dengan URL yang sudah siap pakai. Ambil dengan
otorisasi yang sama seperti pesan itu sendiri.
GET /api/v1/attachment/{id}?mailbox={address}
Selalu menjawab dengan application/octet-stream beserta
Content-Disposition: attachment, apa pun label yang diberikan pengirim.
Itu disengaja: mengembalikan text/html milik orang asing
akan memungkinkan lampiran berjalan sebagai halaman di origin ini. Tipe sebenarnya ada di
JSON pesan, di mana ia berupa data, bukan instruksi.
Error
Setiap kegagalan berupa JSON dengan dua field yang sama, sehingga klien menanganinya
di satu tempat. Status membawa kategorinya, error adalah
slug yang stabil dan dapat dibaca mesin, dan message ditujukan untuk manusia dan
dapat diubah kata-katanya kapan saja.
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_address",
"message": "address must look like name@domain"
}
Jangan pernah membuat percabangan berdasarkan message. Slug yang digunakan adalah invalid_address, bad_cursor, unknown_domain, not_found, rate_limited, daily_limit_reached, unauthorized, dan, khusus di kumpulan premium, quota_reached, overage_cap, overage_funds, address_taken, dan address_limit.
Sebagian error membawa lebih dari dua kolom itu: sebuah hint yang menyebutkan apa yang harus dilakukan, sebuah tautan docs, pada 404 dan 429 sebuah blok premium_pool berisi harga kumpulan dan cara membukanya, serta pada 429 akibat batas gratis sebuah blok upgrade yang menjelaskan batas apa saja yang hilang dengan paket berbayar — ditulis untuk asisten yang membaca isi respons atas nama seseorang, sehingga ia bisa meneruskan pilihan itu alih-alih menyerah.
Batas laju
Gratis, tanpa kunci: 60 permintaan per menit dan 1.000 per hari, per alamat IP. Setiap panggilan ke sebuah kotak masuk ikut dihitung — menampilkan daftar isinya, membaca pesan, badan HTML pesan, lampiran, penghapusan — begitu juga setiap panggilan alat MCP. Hitungan harian disetel ulang pukul 00:00 UTC.
Dengan kunci API gratis, kuota yang sama mengikuti akun Anda, bukan alamat IP Anda — berguna saat panggilan Anda datang dari alamat yang berubah-ubah, seperti runner CI. Akun gratis punya satu kunci, dan kotak masuk yang dibacanya tercantum di kotak masuk Anda. Buat kunci gratis
Di dalam jatah itu, satu pembacaan per detik per alamat: melakukan polling kotak masuk sekali per detik adalah irama yang dimaksudkan.
Paket berbayar bebas dari batas per menit dan batas harian. Kirim kunci paket berbayar sebagai Authorization: Bearer, dan yang tersisa hanyalah batas per alamat dari paket Anda — 2, 3, atau 5 permintaan per detik, di semua domain, dihitung per akun. Premium mulai dari $12,99 per bulan. Lihat paketnya
Kotak masuk di situs ini tidak memakai jatah API gratis: halaman yang dibiarkan terbuka akan terus memeriksa surat masuk selama Anda membutuhkannya.
Melewati batas, Anda akan mendapat 429 dengan header Retry-After dalam detik bulat: rate_limited untuk batas per menit atau per alamat, daily_limit_reached untuk batas harian, disertai sisa waktu hingga tengah malam UTC. Setiap respons atas permintaan gratis menunjukkan sisa jatah Anda: X-RateLimit-Remaining untuk menit berjalan, X-RateLimit-Daily-Remaining untuk hari berjalan.
Retensi
Sebuah pesan dihapus 5 hari
setelah tiba, baik sudah dibaca maupun belum. Setiap pesan membawa
expires_at, jadi Anda tidak perlu menghitung tanggal itu sendiri.
Ini batas keras, bukan pengaturan — tidak ada parameter yang memperpanjangnya. Jika sebuah pesan
harus bertahan lebih lama dari jendela waktu ini, ambil dan simpan di sisi Anda.
Domain Anda sendiri
Arahkan MX Anda ke smtp.grabmail.io dan setiap alamat di
domain Anda akan dijawab melalui endpoint yang sama ini — tidak ada API kedua yang perlu dipelajari,
tidak ada pendaftaran, dan tidak ada kunci.